home *** CD-ROM | disk | FTP | other *** search
/ Alles Voor Internet / Tout Pour Internet / alles voor internet.iso / MacInternet™ / Telnet / NCSA / tn3270 2.4d7 source / tn3270 / grafterm.c < prev    next >
C/C++ Source or Header  |  1992-04-17  |  77KB  |  2,996 lines

  1. /*
  2.  *  tn3270 for the Macintosh Source Code
  3.  *  Brown University Computing and Information Services
  4.  *  Version 2.4d7  April, 1992
  5.  *  Copyright (c) 1988, 1989, 1990, 1991, 1992 by Brown University and by
  6.  *  Peter John DiCamillo.
  7.  *
  8.  *  Permission is granted to any individual or institution to use, copy,
  9.  *  or redistribute the binary version of this software and its
  10.  *  documentation provided this notice and the copyright notices are
  11.  *  retained.  Permission is granted to any individual or non-profit
  12.  *  institution to use, copy, modify, or redistribute the source files
  13.  *  of this software provided this notice and the copyright notices are
  14.  *  retained.  This software may not be distributed for profit, either
  15.  *  in original form or in derivative works, nor can the source be
  16.  *  distributed to other than an individual or a non-profit institution.
  17.  *  Any  individual or group interested in seeing and/or using these
  18.  *  source files but who are prevented from doing so by the above
  19.  *  constraints should contact Don Wolfe, Assistant Vice-President for
  20.  *  Computer Systems at Brown University, (401) 863-7250, for possible
  21.  *  software licensing of the source developed at Brown.
  22.  *
  23.  *  Brown University and Peter John DiCamillo make no representations
  24.  *  about the suitability of this software for any purpose.
  25.  *
  26.  *  BROWN UNIVERSITY AND PETER JOHN DICAMILLO GIVE NO WARRANTY, EITHER
  27.  *  EXPRESS OR IMPLIED, FOR THE PROGRAM AND/OR DOCUMENTATION PROVIDED,
  28.  *  INCLUDING, WITHOUT LIMITATION, WARRANTY OF MERCHANTABILITY AND
  29.  *  WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE.
  30.  *
  31.  */
  32.  
  33. #if !defined(USEDUMP)
  34.     #include "maclib.h"
  35.     #include "termdef.h"
  36.     #include "tn3270funcs.h"
  37.     #include "globals.h"
  38. #else
  39.     #pragma load "tn3270DumpFile"
  40. #endif
  41.  
  42. #include "telnet.h"
  43.  
  44. #define adMin         39
  45. #define adMax         37
  46.  
  47. /* location for disk initialization dialog */
  48. #define kDITop        0x0050
  49. #define kDILeft        0x0070
  50.  
  51. #define gestaltPPCSupportsRealTime    0x1000
  52.  
  53. extern vmprt prtinfo;                /* WMAC print format definition */
  54. extern Handle rcvMessage;            /* PPC message buffers */
  55. extern Handle sndMessage;
  56.  
  57. struct Point sfppoint, sfgpoint;    /* standard file dialog locations */
  58. char da_menu = 0;                    /* TRUE when DA menu should be displayed */
  59. char showstg = 0;                    /* True when storage info. wanted */
  60. int button;                            /* button down at startup */
  61. short systemvol;                    /* volume with system files */
  62. extern int defaultv;                /* default volume for TCP/IP FTP */
  63. int *DirTree;                        /* for NCSA FTP server */
  64. char *mungbuf;                        
  65.  
  66. GDHandle bitmap_gdev;                /* gdev used for bitmaps */
  67. GDHandle saved_gdev;                /* gdev for set/rest gdev */
  68.  
  69. extern unsigned char kbtyp[];        /* key mapping tables */
  70. extern unsigned char kbstd[];
  71. extern unsigned char kbapl[];
  72. unsigned char ordertab[256];        /* table checking for 3270 order vs. data */
  73.  
  74. short launchvol;            /* default volume at launch */
  75. char smallscreen;            /* complete 24 x 80 window doesn't fit */
  76. char notifyavail = 0;        /* Notification Manager available */
  77. nmrmessage *myNMR[NMRNUM];    /* pointers to Notification Manager messages */
  78.  
  79. static unsigned char * ScrDmpEnb = (unsigned char *)0x2f8;
  80.  
  81. RGBColor realblack = {0, 0, 0};
  82. RGBColor realwhite = {0xffff, 0xffff, 0xffff};
  83.  
  84. main()
  85. {
  86. short rc;
  87. unsigned char dummy[28];
  88. short rid;
  89. ResType rtype;
  90. Rect deskrect;
  91. unsigned short height, width;
  92. Handle temph;
  93. char changed;
  94. short i;
  95.  
  96. ftpcopen = ftpdopen = ftplopen = 0;        /* no TCP/IP FTP yet */
  97. sndactive = 0;                    /* no sound currently active */
  98. prtinit = 0;                    /* printing not initialized */
  99. scrapstart = 0;                    /* no private scrap storage */
  100. smallscreen = 0;                /* assume window will fit */
  101. smgr_sppc =0;                    /* no SPPC registrations yet */
  102. smgrppc = 0;                    /* no PPC ports yet */
  103. rcvMessage = sndMessage = 0;    /* no ppc buffers yet */
  104. GetVol(dummy, &launchvol);        /* define launchvol */
  105. defaultv = launchvol;            /* also use for FTP */
  106. normcurs = &qd.arrow;            /* default Macintosh cursor */
  107.  
  108.                         /* initialize connection record pointers */
  109. for (i=0; i < MAXSESSIONS; i++)
  110.     cplist[i] = 0;
  111.  
  112.                         /* define handle to EBCDIC to ASCII table */
  113. xtabh = GetResource('GFXT', 128);
  114. alaxtabh = GetResource('GFXT', 129);
  115.                         /* define prtinfo */
  116. temph = GetResource('VMPR', 128);
  117. if (temph != 0) {
  118.     memcpy(&prtinfo, *temph, sizeof(vmprt));
  119.     if (prtinfo.linewidth > MAXLINEWIDTH) prtinfo.linewidth = MAXLINEWIDTH;
  120.     if (prtinfo.titlewidth > MAXLINEWIDTH) prtinfo.titlewidth = MAXLINEWIDTH;
  121.     }
  122.  
  123. orderinit();            /* initialize ordertab */
  124.  
  125. macinit();                /* general Mac initialization */
  126. hnd_init();                /* handle any update events */
  127.  
  128.                         /* calculate limits for screen format */
  129. getdeskrect(&deskrect);
  130. height = deskrect.bottom;
  131. height -= deskrect.top;
  132. height -= 47;
  133.         /* If the top of the desk rectangle is <= 0, it includes the
  134.            menu bar, and the size of the menu bar is subtracted */
  135. if (deskrect.top <= 0) {
  136.     height -= 20;
  137.     }
  138. width = deskrect.right;
  139. width -= deskrect.left;
  140. width -= 13;
  141.  
  142.     /* calculate 9 and 12-point limits */
  143. rowmax9 = height/12;
  144. if (rowmax9 < 24) {
  145.     rowmax9 = 24;
  146.     smallscreen = 1;
  147.     }
  148. colmax9 = width/6;
  149. if (colmax9 < 80) {
  150.     colmax9 = 80;
  151.     }
  152. rowmax12 = height/16;
  153. colmax12 = width/7;
  154.  
  155. rc = ioinit();                /* initialize drivers */
  156.                             /* also sets default connection type (ds.setsflg) */
  157. if (rc != 0) {
  158.     macend();
  159.     return;
  160.     }
  161. appl_menu();
  162.                             /* adjust default settings for this invocation */
  163.                                 /* screen size */
  164. adjfmt(&changed, &(ds.windmax), &(ds.dfltptsize), &(ds.altptsize),
  165.        &(ds.altrows), &(ds.altcols));
  166.                                 /* host name */
  167. if (ds.setsflg == 2) tcpdflthost(dshostname);
  168. else if (ds.setsflg == 1) serdflthost(dshostname);
  169. else sadflthost(dshostname);
  170.                                 /* keymap handle and name */
  171. c2pstr(dskybdname);
  172. default_kybdhandle = GetNamedResource('GFKB', dskybdname);
  173. p2cstr(dskybdname);
  174. if (default_kybdhandle == 0L) {
  175.     stoperr(kbdefalrt, 0);
  176.     ioend();
  177.     macend();
  178.     return;
  179.     }
  180. else {
  181.     GetResInfo(default_kybdhandle, &rid, &rtype, dskybdname);
  182.     p2cstr(dskybdname);
  183.     }
  184.                                 /* national language name */
  185. GetItem(nlMenu, 1, dsnlname);
  186. p2cstr(dsnlname);
  187.                                 /* for 12-point font, frame -> bold, */
  188. if (ds.dfltptsize == 12) {        /* blink -> frame                     */
  189.     ds.attrmap[1] = 0x08;
  190.     ds.attrmap[4] = 0x40;
  191.     }
  192.  
  193.                             /* set new session config. to defaults */
  194. copyconfig(&ds, dshostname, dswtitle);
  195.  
  196. dfltcurs = 0;                /* normal cursor after initialization */
  197. arrowcursor();
  198.  
  199. read_settings(1, 0);        /* use settings files from launch time */
  200.  
  201. done = false;
  202. while (!done) hndmac();        /* handle Mac events and I/O */
  203.  
  204. ioend();                    /* clean-up drivers */
  205. macend();                    /* clean-up Mac */
  206. }
  207.  
  208. void macinit(void)
  209. {
  210. short i;
  211. static pascal void (*attnhdl) (short msg, MenuHandle mhdl, Rect *mr,
  212.                      Point hit, short *which);
  213. SysEnvRec theWorld;
  214. GDHandle currGD;
  215. PixMapHandle currPM;
  216. Rect deskrect;
  217. OSErr rc;
  218. CursHandle watchHandle;
  219.  
  220.                         /* set-up general Macintosh environment */
  221. MaxApplZone();                /* set-up for efficient storage use */
  222. for (i=0; i < 4; i++) MoreMasters();
  223. InitGraf(&qd.thePort);
  224. FlushEvents(everyEvent, 0);
  225. InitWindows();
  226. InitFonts();
  227. InitMenus();
  228. InitDialogs(0L);
  229. InitCursor();
  230. TEInit();
  231.  
  232.             /* watch cursor at start */
  233. watchHandle = GetCursor(4);
  234. SetCursor(*watchHandle);
  235. dfltcurs = 0;
  236.  
  237.             /* set-up menus */
  238. for (i=0; i < NMENUS; i++) {
  239.     myMenus[i] = GetMenu(256+i);
  240.     if (i == 4) {        /* attn key menu */
  241.         attnhdl = attnmenu;
  242.         (*myMenus[4])->menuProc = (Handle)&attnhdl;
  243.         CalcMenuSize(myMenus[4]);
  244.         (*myMenus[4])->enableFlags = 1;
  245.         }
  246.     InsertMenu(myMenus[i], 0);
  247.     }
  248. AddResMenu(myMenus[0], 'DRVR');
  249.  
  250. nlMenu = GetMenu(234);
  251. InsertMenu(nlMenu, -1);
  252. AddResMenu(nlMenu, 'GFNL');
  253.  
  254. kybdMenu = GetMenu(235);
  255. InsertMenu(kybdMenu, -1);
  256. AddResMenu(kybdMenu, 'GFKB');
  257.  
  258. configMenu = GetMenu(236);
  259. InsertMenu(configMenu, -1);
  260.  
  261. appl_menu();    /* draw menu bar with appropriate menus enabled */
  262.  
  263.                 /* check if mouse is down at startup */
  264. button = Button(); 
  265.  
  266.             /* get environment information */
  267. rc = SysEnvirons(1, &theWorld);        
  268. newroms = (theWorld.machineType >= 0);
  269. colormac = (theWorld.hasColorQD != 0);
  270. systemvol = theWorld.sysVRefNum;
  271. syslevel = theWorld.systemVersion >> 8;
  272. notifyavail = (syslevel >= 6);
  273. newkybd = extkybd = 0;        /* assume original keyboard */
  274. if (rc == 0) {                /* SysEnvirons trap exists */
  275.     if (theWorld.keyBoardType == envAExtendKbd) newkybd = extkybd = 1;
  276.     else if (theWorld.keyBoardType == envStandADBKbd) newkybd = 1;
  277.     }
  278.  
  279. if (colormac) {        /* We have color QuickDraw, now check if        */
  280.                     /* the deepest display device supports color.    */
  281.                     /* We won't use color if the device is            */
  282.                     /* monochrome and the current pixel size        */
  283.                     /* is 1.  Ideally, we would be able to            */
  284.                     /* decide based on the maximum pixel size.        */
  285.     getdeskrect(&deskrect);
  286.     currGD = myGetMaxDevice(&deskrect);
  287.     currPM = (*currGD)->gdPMap;
  288.     if ((*currPM)->pixelSize == 1) 
  289.         colormac = (*currGD)->gdFlags & (1 << gdDevType);
  290.     }
  291.  
  292. /* determine if Gestalt is available */
  293. gestaltavail = 0;
  294. if (newroms) {       /* compare Gestalt OS trap to Unimplemented Toolbox trap */
  295.     gestaltavail = NGetTrapAddress(0xAD, 0) !=
  296.                    NGetTrapAddress(0x9F, 1);
  297.     }
  298.  
  299. /* determine availability of PPC */
  300. ppcavail = 0;
  301. ppcflags = 0;
  302. if (gestaltavail) {
  303.     rc = Gestalt('ppc ', (long *)&ppcflags);
  304.     ppcavail = (rc == noErr);
  305.     if (!ppcavail) ppcflags = 0;
  306.     }
  307.  
  308. screenRect = qd.screenBits.bounds;
  309.  
  310.             /* read alerts into memory and center */
  311. ctralrt(263);
  312. ctralrt(264);
  313. ctralrt(265);
  314. ctralrt(274);
  315. ctralrt(275);
  316. ctralrt(276);
  317. ctralrt(278);
  318. ctralrt(279);
  319. ctralrt(281);
  320. ctralrt(288);
  321. ctralrt(289);
  322.  
  323.             /* calculate standard file dialog location*/
  324. sfppoint.h = (screenRect.right-screenRect.left-304)/2;
  325. sfgpoint.h = (screenRect.right-screenRect.left-348)/2;
  326. if (smallscreen) {
  327.     sfppoint.v = (screenRect.bottom-screenRect.top-184)/2;
  328.     sfgpoint.v = (screenRect.bottom-screenRect.top-200)/2;
  329.     }
  330. else {
  331.     sfppoint.v = (screenRect.bottom-screenRect.top-184)/3;
  332.     sfgpoint.v = (screenRect.bottom-screenRect.top-200)/3;
  333.     }
  334.  
  335. if (colormac) {
  336.     getdeskrect(&dragRect);
  337.     }
  338. else {
  339.     SetRect(&dragRect, 0, 24, screenRect.right-4, screenRect.bottom-4);
  340.     }
  341.  
  342.             /* allocate storage for notification manager */
  343. if (notifyavail) {
  344.     myNMR[0] = (nmrmessage *)NewPtr((long)(sizeof(nmrmessage)*NMRNUM));
  345.     if (myNMR[0] == 0L) {
  346.         notifyavail = 0;
  347.         stgalert("nmrmessages", "NewPtr", (long)(sizeof(nmrmessage)*NMRNUM));
  348.         ExitToShell();
  349.         }
  350.     memset(myNMR[0], 0, sizeof(nmrmessage)*NMRNUM);        
  351.     for (i=1; i < NMRNUM; i++) {
  352.         myNMR[i] = myNMR[0] + i;
  353.         }
  354.     }
  355.  
  356.             /* allocate sound channel storage (about 1K) */
  357. scp = (SndChannelPtr)NewPtr((long)(sizeof(struct SndChannel)));
  358. if (scp == 0L) {
  359.     stgalert("sound channel", "NewPtr", (long)(sizeof(struct SndChannel)));
  360.     ExitToShell();
  361.     }
  362. memset(scp, 0, sizeof(struct SndChannel));
  363. scp->qLength = stdQLength;
  364.  
  365.  
  366.             /* allocate print record */
  367. hPrint = (THPrint)NewHandle((long)sizeof(struct TPrint));
  368. if (hPrint == 0L) {
  369.     stgalert("print record", "NewHandle", (long)(sizeof(struct TPrint)));
  370.     ExitToShell();
  371.     }
  372.  
  373.             /* allocate storage for FTP server */
  374. DirTree = (int *)NewPtr(256*sizeof(int));
  375. if (DirTree == 0L) {
  376.     stgalert("DirTree", "NewPtr", (long)(256*sizeof(int)));
  377.     ExitToShell();
  378.     }
  379. mungbuf = (char *)NewPtr(1024);
  380. if (mungbuf == 0L) {
  381.     stgalert("mungbuf", "NewPtr", 1024);
  382.     ExitToShell();
  383.     }
  384.  
  385.             /* allocate work region */
  386. temprgn = NewRgn();
  387. if (temprgn == 0L) {
  388.     stgalert("temp grow icon region", "NewRgn", 0L);
  389.     ExitToShell();
  390.     }
  391.  
  392.             /* miscellaneous initialization */
  393. CouldDialog(256);
  394. ScrDmpSav = *ScrDmpEnb;        /* save current byte */
  395. sw_bgrnd = 0;                /* not in switcher background */
  396. mf_bgrnd = 0;                /* not in MultiFinder background */
  397.  
  398.             /* check if there is any text to paste */
  399. importscrap();
  400.  
  401. /* if PPC is available, initialize it */
  402. if (ppcavail) {
  403.     if ((ppcflags & gestaltPPCSupportsRealTime) == 0) {
  404.         rc = PPCInit();
  405.         if (rc == noErr) {
  406.             rc = Gestalt('ppc ', (long *)&ppcflags);
  407.             }
  408.         if (rc != noErr) {
  409.             ppcavail = 0;
  410.             ppcflags = 0;
  411.             stoperr(ppcinitalrt, 0);
  412.             }
  413.         }
  414.     }
  415.  
  416. /* if ppc will be used, initialize queues */
  417. if (ppcavail) {
  418.     initparamblocks();
  419.     initclientrecs();
  420.     initdatablocks();
  421.     addparamblocks();
  422.     addclientrecs();
  423.     adddatablocks();
  424.     }
  425.  
  426. apiregister(0, 0);        /* attempt to register session mgr with sppc and ppc */
  427. }
  428.  
  429. OSErr ioinit(void)
  430. {
  431. OSErr rc;
  432.                         /* initialize each driver type */
  433.                         /* non-zero return code indicates driver
  434.                            is not present (just a stub routine) */
  435. haveserial = havetcp = havesa = 0;
  436. ds.setsflg = 99;
  437. rc = ser_init();            /* serial */
  438. if (rc == 0) {
  439.     haveserial = 1;
  440.     ds.setsflg = 1;            /* make commdlg default */
  441.     }
  442. if (rc < 0) {
  443.     return(rc);
  444.     }
  445.     
  446. rc = sa_init();                /* standalone */
  447. if (rc == 0) {
  448.     havesa = 1;
  449.     ds.setsflg = 0;            /* make commdlg default */
  450.     }
  451. if (rc < 0) {
  452.     if (haveserial) ser_end();
  453.     return(rc);
  454.     }
  455.     
  456. rc = tcp_init();            /* tcpip */
  457. if (rc == 0) {
  458.     havetcp = 1;
  459.     ds.setsflg = 2;            /* make commdlg default */
  460.     }
  461. if (rc < 0) {
  462.     if (haveserial) ser_end();
  463.     if (havesa) sa_end();
  464.     return(rc);
  465.     }
  466. if (ds.setsflg < 99) return(0);
  467. return(1);                    /* no usable driver */
  468. }
  469.  
  470. void hnd_init(void)            /* handle update events during intialization */
  471. {
  472. short evtrc;
  473.  
  474. evtrc = GetNextEvent(updateMask, &myEvent);
  475. while (evtrc != 0) {
  476.     switch(myEvent.what) {
  477.         case updateEvt:
  478.                                 updevent((GrafPtr)myEvent.message);
  479.                                 break;
  480.         default:
  481.                                 break;
  482.         }
  483.     evtrc = GetNextEvent(updateMask, &myEvent);
  484.     }
  485. }
  486.  
  487. /* newlogin is called to establish a network connection, which will
  488.    in turn create a new window if the connection is successful.  The
  489.    appropriate driver's "login" routine is called with the connection
  490.    record for the connection.                                            */
  491.  
  492. void newlogin(char apiopen,
  493.               char fileopen, unsigned char *fname, short vnum,
  494.               unsigned char oldformat)
  495. {
  496. short i, sess_index;
  497. cnr *cp;
  498. char driverok;
  499. OSErr rc;
  500. Size allocsize;
  501.  
  502.                                         /* find a free cplist slot */
  503. sess_index = 0;
  504. for (i=0; i < MAXSESSIONS; i++) {
  505.     if (cplist[i] == 0) {
  506.         sess_index = i+1;
  507.         break;
  508.         }
  509.     }
  510. if (sess_index == 0) {                    /* no sessions available */
  511.     if (apiopen) {
  512.         apiopenerr(openNoSessions, 0);
  513.         if (apiopenreq.noalert) return;
  514.         }
  515.     stoperr(sesslimalrt, 0);
  516.     return;
  517.     }
  518. sess_index--;
  519.                                         /* allocate new connection record */
  520. cp = cplist[sess_index] = (cnr *)NewPtr((Size)sizeof(cnr));
  521. if (cp == 0) {                                /* no storage */
  522.     if (apiopen) {
  523.         apiopenerr(openNoMemory, 0);
  524.         if (apiopenreq.noalert) return;
  525.         }
  526.     stoperr(newsesalrt, 0);
  527.     return;
  528.     }
  529. memset(cp, 0, sizeof(cnr));                /* initialize to 0 */
  530.  
  531.                                 /* define connection record */
  532.                                 /* first variables which can't cause errors */
  533.                                 /* (allows record to be used for some purposes,
  534.                                    such as "apinoalert" checking)            */
  535. cp->rballoc = 4101;        /* limits responses to 4K (first 5 bytes not included) */
  536.  
  537. cp->inrect.top = cp->inrect.left = 32767;
  538. cp->inrect.bottom = cp->inrect.right = -32767;
  539.  
  540. if (apiopen) {
  541.     cp->apiopenrefnum = apiopenrefnum;
  542.     cp->apiopensref = apiopensref;
  543.     cp->apiopenmsgid = apiopenmsgid;
  544.     cp->apiopenkind = apiopenkind;
  545.     cp->apiopen = cp->apiopenpend = 1;
  546.     cp->apinoalert = apiopenreq.noalert;
  547.     cp->apihide = apiopenreq.hide;
  548.     }
  549.  
  550. if (fname != 0) strcpy(cp->s_fName, fname);
  551. cp->stdfont = NORMALFONT;
  552. if (vnum != 0) {
  553.     cp->vnum = vnum;
  554.     }
  555. else {
  556.     cp->vnum = launchvol;
  557.     }
  558. if (fileopen) {
  559.     cp->fsoldformat = oldformat;
  560.     }
  561.                                         /* define settings */
  562. if (apiopen) {                                    /* open via api */
  563.     ns = ds;
  564.     ns.dfltptsize = apiopenreq.dfltsize.ptsize;
  565.     ns.altptsize = apiopenreq.altsize.ptsize;
  566.     ns.altrows = apiopenreq.altsize.rows;
  567.     ns.altcols = apiopenreq.altsize.cols;
  568.     ns.ext3270 = (apiopenreq.nowsf == 0);
  569.     strcpy(nshostname, apihostname);
  570.     strcpy(nswtitle, apiwindowname);
  571.     strcpy(nskybdname, dskybdname);
  572.     strcpy(nsnlname, dsnlname);
  573.     strcpy(nssndname, dssndname);
  574.     }
  575. else if (fileopen == 0) {                        /* open from menu */
  576.     ns = ds;
  577.     ns.dblevel = cf_dblevel;
  578.     ns.setsflg = cf_setsflg;
  579.     ns.timeout = cf_timeout;
  580.     ns.retries = cf_retries;
  581.     ns.dfltptsize = cf_dfltptsize;
  582.     ns.altptsize = cf_altptsize;
  583.     ns.altrows = cf_altrows;
  584.     ns.altcols = cf_altcols;
  585.     ns.custrows = cf_custrows;
  586.     ns.custcols = cf_custcols;
  587.     ns.windmax = cf_windmax;
  588.     ns.savewpos = cf_savewpos;
  589.     ns.ext3270 = cf_ext3270;
  590.     ns.nographics = cf_nographics;
  591.     ns.nocolor = cf_nocolor;
  592.     strcpy(nshostname, cf_hostname);
  593.     strcpy(nswtitle, cf_wtitle);
  594.     strcpy(nskybdname, dskybdname);
  595.     strcpy(nsnlname, dsnlname);
  596.     strcpy(nssndname, dssndname);
  597.     }
  598.                                 /* update connection record for settings */
  599.                                     /* define settings which won't be changed */
  600. cp->cs.setsflg = ns.setsflg;
  601. cp->serflg = (ns.setsflg == 1);
  602. cp->tcpflg = (ns.setsflg == 2);
  603. cp->cs.altrows = ns.altrows;
  604. cp->cs.altcols = ns.altcols;
  605. cp->addr14 = (cp->cs.altrows * cp->cs.altcols) > 4096;
  606. strcpy(cp->cshostname, nshostname);
  607. strcpy(cp->fshostname, nshostname);
  608. strcpy(cp->cswtitle, nswtitle);
  609. strcpy(cp->fswtitle, nswtitle);
  610.                                     /* initialize kybd, nl, snd data */
  611.                                     /* (may also not be changed) */
  612. strcpy(cp->cskybdname, dskybdname);
  613. cp->kb_handle = default_kybdhandle;
  614. strcpy(cp->csnlname, dsnlname);
  615. strcpy(cp->cssndname, dssndname);
  616.                                     /* do the update */
  617. settings_update(&ns, nswtitle, nskybdname, nsnlname, nssndname, cp);
  618.  
  619.                                 /* check selected driver is available */
  620. if (cp->serflg) {
  621.     driverok = haveserial;
  622.     }
  623. else if (cp->tcpflg) {
  624.     driverok = havetcp;
  625.     }
  626. else {
  627.     driverok = havesa;
  628.     }
  629. if (driverok == 0) {                        /* specified driver not present */
  630.     stoperr(nodrvalrt, cp);
  631.     if (cp->sndhandle != 0) {            /* clean-up connection */
  632.         DisposHandle(cp->sndhandle);
  633.         }
  634.     DisposPtr((Ptr)cp);
  635.     cplist[sess_index] = 0;
  636.     return;
  637.     }
  638.                                 /* allocate work regions */
  639. cp->cliprgn = NewRgn();
  640. if (cp->cliprgn == 0) {
  641.     stoperr(newwindalrt, cp);
  642.     if (cp->sndhandle != 0) {            /* clean-up connection */
  643.         DisposHandle(cp->sndhandle);
  644.         }
  645.     DisposPtr((Ptr)cp);
  646.     cplist[sess_index] = 0;
  647.     return;
  648.     }
  649. cp->destrgn = NewRgn();    
  650. if (cp->destrgn == 0) {
  651.     stoperr(newwindalrt, cp);
  652.     DisposeRgn(cp->cliprgn);            /* clean-up connection */
  653.     if (cp->sndhandle != 0) {
  654.         DisposHandle(cp->sndhandle);
  655.         }
  656.     DisposPtr((Ptr)cp);                        
  657.     cplist[sess_index] = 0;
  658.     return;
  659.     }
  660.                                 /* allocate storage which depends on logical
  661.                                    screen size (but not any storage associated
  662.                                    with the window itself) */
  663. rc = newscrap(cp);                    /* scrap */
  664. if (rc != noErr) {                        /* no memory for minimum scrap */
  665.     stoperr(newwindalrt, cp);
  666.     DisposeRgn(cp->cliprgn);            /* clean-up connection */
  667.     DisposeRgn(cp->destrgn);
  668.     if (cp->sndhandle != 0) {
  669.         DisposHandle(cp->sndhandle);
  670.         }
  671.     DisposPtr((Ptr)cp);
  672.     cplist[sess_index] = 0;
  673.     return;
  674.     }
  675.                                     /* translation buffer = screen width */
  676. allocsize = cp->cs.altcols;
  677. cp->nlbuff = (unsigned char *)myNewPtr(allocsize, cp);
  678. if (cp->nlbuff == 0) {
  679.     stoperr(newsesalrt, cp);
  680.     DisposeRgn(cp->cliprgn);            /* clean-up connection */
  681.     DisposeRgn(cp->destrgn);
  682.     if (cp->sndhandle != 0) {
  683.         DisposHandle(cp->sndhandle);
  684.         }
  685.     DisposPtr((Ptr)cp);
  686.     cplist[sess_index] = 0;
  687.     return;
  688.     }
  689. memset(cp->nlbuff, 0, (short)allocsize);
  690.  
  691.                                     /* 3270 screen buffer */
  692. allocsize *= cp->cs.altrows;
  693. cp->chrbuff = (unsigned char *)myNewPtr(allocsize, cp);
  694. if (cp->chrbuff == 0) {
  695.     stoperr(newsesalrt, cp);
  696.     DisposPtr(cp->nlbuff);                /* clean-up connection */
  697.     DisposeRgn(cp->cliprgn);
  698.     DisposeRgn(cp->destrgn);
  699.     if (cp->sndhandle != 0) {
  700.         DisposHandle(cp->sndhandle);
  701.         }
  702.     DisposPtr((Ptr)cp);
  703.     cplist[sess_index] = 0;
  704.     return;
  705.     }
  706. memset(cp->chrbuff, 0, (short)allocsize);
  707.  
  708.                                     /* 3270 attribute buffer */
  709. allocsize *= 2;
  710. cp->atrbuff = (unsigned short *)myNewPtr(allocsize, cp);
  711. if (cp->atrbuff == 0) {
  712.     stoperr(newsesalrt, cp);
  713.     DisposPtr(cp->chrbuff);                /* clean-up connection */
  714.     DisposPtr(cp->nlbuff);
  715.     DisposeRgn(cp->cliprgn);
  716.     DisposeRgn(cp->destrgn);
  717.     if (cp->sndhandle != 0) {
  718.         DisposHandle(cp->sndhandle);
  719.         }
  720.     DisposPtr((Ptr)cp);
  721.     cplist[sess_index] = 0;
  722.     return;
  723.     }
  724. memset(cp->atrbuff, 0, (short)allocsize);
  725.  
  726.                                     /* prompt for actual host name if ?
  727.                                        was specified */
  728. strcpy(cp->connhostname, cp->cshostname);
  729. if (strcmp(cp->connhostname, "?") == 0) {
  730.     strcpy(cp->connhostname, "");        /* initial value for hostdlg */
  731.     rc = hostdlg(cp->connhostname);
  732.     if (rc != noErr) {
  733.         DisposPtr((Ptr)(cp->atrbuff));            /* clean-up connection */
  734.         DisposPtr((Ptr)(cp->chrbuff));    
  735.         DisposPtr((Ptr)(cp->nlbuff));
  736.         DisposeRgn(cp->cliprgn);
  737.         DisposeRgn(cp->destrgn);
  738.         if (cp->sndhandle != 0) {
  739.             DisposHandle(cp->sndhandle);
  740.             }
  741.         DisposPtr((Ptr)cp);
  742.         cplist[sess_index] = 0;
  743.         return;
  744.         }
  745.     }
  746. strcpy(cp->hostonly, cp->connhostname);    /* host name (only) for this session */
  747. for (i=0; i < 256; i++) {
  748.     if (cp->hostonly[i] == '\0') break;
  749.     if (cp->hostonly[i] == ':') {
  750.         cp->hostonly[i] = '\0';
  751.         break;
  752.         }
  753.     }
  754. def_sessname(cp);                    /* define descriptive name */
  755. new_connmenu();                        /* add to connections menu */
  756. appl_menu();                        /* possible update to connections menu */
  757.  
  758.                                     /* attempt to open a connection */
  759. if (cp->serflg) {
  760.     serlgin(cp);
  761.     }
  762. else if (cp->tcpflg) {
  763.     tcplgin(cp);
  764.     }
  765. else {
  766.     salgin(cp);
  767.     }
  768. }
  769.               
  770. void removeconnection(cnr *cp)
  771. {
  772. short i;
  773.  
  774. if (cp->myWindow != 0) return;        /* when user wants connection to persist */
  775.  
  776. if (cp->apiopen && cp->apiopenpend) apiopenerr(openConnFailed, cp);
  777.  
  778. DisposPtr((Ptr)(cp->atrbuff));
  779. DisposPtr((Ptr)(cp->chrbuff));    
  780. DisposPtr((Ptr)(cp->nlbuff));
  781. DisposeRgn(cp->cliprgn);
  782. DisposeRgn(cp->destrgn);
  783. if (cp->sndhandle != 0) {
  784.     DisposHandle(cp->sndhandle);
  785.     }
  786. if (cp->pastebuff != 0) DisposPtr(cp->pastebuff);
  787.  
  788. if (new_settings(cp)) {
  789.     if (savedlg(0, cp)) write_settings(cp);
  790.     }
  791. else {
  792.     if (cp->fsoldformat) {
  793.         if (savedlg(1, cp)) write_settings(cp);
  794.         }
  795.     }
  796.     
  797. for (i=0; i < MAXSESSIONS; i++) {
  798.     if (cplist[i] == cp) {
  799.         cplist[i] = 0;
  800.         break;
  801.         }
  802.     }
  803. DisposPtr((Ptr)cp);
  804. new_connmenu();
  805. appl_menu();                /* possible update to connections menu */
  806. }
  807.  
  808.  
  809. /* login_init initializes variables for a new host session.  It may be called
  810.    to create a new session with a connection record which has been in use,
  811.    as well as a new connection record.                                    */
  812.  
  813. void login_init(cnr *cp)
  814. {
  815.                         /* reset file transfer status */
  816. xfrst(cp);
  817.                         /* 3270 data stream processing */
  818. cp->rbsize = 0;
  819. cp->ldvoff = 0;
  820. cp->curadr = 0;
  821. cp->bufadr = 0;
  822. cp->chratr = 0;
  823. cp->rdaid = 0x60;
  824. cp->skipnewmode = 0;
  825.                         /* line mode processing */
  826. cp->skiplf = 0;                /* reset line mode flags */
  827. cp->escmode = 0;
  828. cp->serverconn = 0;            /* no non-telnet server */
  829. cp->servermode = 0;            /* reset non-telnet mode */
  830. cp->serverflags = 0;        /* reset flags */
  831.                         /* telnet protocol */
  832. cp->telrcv_state = 0;        /* initialize FSA */
  833. cp->askedSGA = 0;            /* haven't negotiated SGA yet */
  834. cp->data_init = 1;            /* first data byte will begin write */
  835. cp->sent3270tt = 0;            /* haven't sent 3270 terminal type */
  836. cp->hadascii = 0;            /* no ascii data yet */
  837. cp->newserver = 0;            /* assume not new server */
  838. memset(cp->hisopts, 0, 256);    /* initialize option flags */
  839. memset(cp->myopts, 0, 256);
  840.                         /* keyboard */
  841. cp->kbqsize = 0;            /* reset keyboard queue */
  842. cp->kblock = 1;                /* initialize status line variables */
  843. cp->kblcode = 4;
  844. cp->kb_err = 0;                /* reset kb entry error code */
  845.                         /* various control variables */
  846. cp->connstate = 0;            /* default connection state */
  847. cp->ioerror = 0;
  848. cp->fsinv = 0;                /* reset pending invldscr */
  849. cp->drawpict = 0;            /* no graphics */
  850. cp->newpict = 1;
  851. cp->online = 0;
  852. cp->logon = 0;                /* not logged-in to server */
  853. cp->pndbeep = 0;            /* no pending bell */
  854. cp->pndclr = 0;                /* no pending clrpict */
  855. cp->needwrite = 0;            /* no call to writescr needed */
  856. cp->wr_active = 0;            /* statline write not active */
  857. cp->statcpos = 0;
  858. cp->showfkey = 0;            /* fkeys disabled */
  859. cp->wsfflag = 0;            /* not accumulating WSF data */
  860. cp->myport = 0;                /* no port */
  861. cp->inschar = 0;
  862. cp->quitflg = 0;
  863. cp->hostok = 0;
  864. cp->last_t = 0;
  865. cp->last_stat_time = 99;
  866. strcpy(cp->statresult, "");
  867. cp->colorfield = 0;
  868. cp->cutflag = 0;
  869. cp->attrloc = 0;
  870. cp->savedvalid = 0;
  871.                             /* graphics init */
  872. cp->dfltcolor = 4;                /* default color =  green */
  873. cp->dfltlw = 1;                    /* default line width = 1 pixel */
  874. cp->dfltlt = 7;                    /* default line type = solid */
  875. cp->dfltmarker = 0xb5;            /* default marker = diamond */
  876. cp->dfltmix = 2;                /* default mix mode */
  877.                                 /* default area pattern */
  878. memset(&(cp->dfltpat), 0xff, sizeof(Pattern));
  879. cp->linew = 1;                    /* current line width */
  880. cp->linet = 7;                    /* current line type */
  881. cp->copymode = srcCopy;            /* current mode for CopyBits */
  882. cp->pictopen = 0;                /* true when PICT file is open */
  883. strcpy(cp->pict_fName, "\p");    /* name of open PICT file (pascal) */
  884. cp->area_active = 0;            /* flag to indicate area is active */
  885. cp->image_active = 0;            /* flag to indicate image data is active */
  886. cp->markchar = 0xb5;            /* current marker */
  887.                                 /* current area pattern */
  888. memset(&(cp->fillpat), 0xff, sizeof(Pattern));    
  889. cp->markstr[0] = 1;                /* one-byte Pascal string */
  890. cp->markstr[1] = 0;
  891. cp->openflg = 0;
  892.  
  893.                         /* show new status */
  894. if (cp->myWindow != 0) newstat(cp);
  895. appl_menu();
  896. }
  897.  
  898. void sessionlgout(char keep, cnr *cp)
  899. {
  900. if (cp->apiopen && cp->apiopenpend) apiopenerr(openConnFailed, cp);
  901. cp->apiopen = 0;
  902. if (cp->connstate > 3) {
  903.     closeresponse(closeUnknown, cp);
  904.     apideregister(1, cp);        /* deregister session */
  905.     }
  906. cp->online = cp->logon = 0;
  907. cp->kbqsize = 0;
  908. cp->kblock = 1;
  909. if (cp->kblcode != 3) cp->kblcode = 4;
  910. cp->connstate = 0;
  911. cp->myport = 0;
  912. cp->showfkey = 0;
  913. if (cp->myWindow != 0) {
  914.     newstat(cp);
  915.     if (!(cp->cs.keepwindow && keep)) {
  916.         removewindow(cp);
  917.         }
  918.     }
  919. removeconnection(cp);    /* no-op if window is still there */
  920. }
  921.  
  922. /*    createwindow is called to create a new window for a session.
  923.     It is also called to initialize variables when the api doesn't
  924.     require a window.                                            */
  925.  
  926. OSErr createwindow(cnr *cp)
  927. {
  928. OSErr rc;
  929.  
  930.                         /* create new window with alt. size */
  931. cp->ewamode = 1;
  932. rc = newmode(1, 1, cp);
  933. if (rc != noErr) {
  934.     stoperr(newwindalrt, cp);
  935.     return(rc);
  936.     }
  937.  
  938. if (cp->myWindow == 0) return(noErr);    /* possible with api */
  939.  
  940. clrscn(cp);
  941. invldscr(cp);
  942. return(noErr);
  943. }
  944.  
  945. void removewindow(cnr *cp)        /* completely remove window */
  946. {
  947. short i, count;
  948.  
  949. count = 0;                        /* count current number of windows */
  950. for (i=0; i < MAXSESSIONS; i++) {
  951.     if (cplist[i] != 0) {
  952.         if ((cplist[i])->myWindow != 0) count++;
  953.         }
  954.     }
  955.  
  956. updwindpos(cp);
  957. removebitmaps(cp);
  958. if (colormac && (count == 1)) {
  959.     restorectab();
  960.     }
  961. CloseWindow(cp->myWindow);
  962. cp->myWindow = 0;
  963. if (count == 1) {
  964.     arrowcursor();
  965.     (*ScrDmpEnb) = ScrDmpSav;
  966.     }
  967. appl_menu();
  968. }
  969.  
  970. void removebitmaps(cnr *cp)
  971. {
  972. if (colormac && (!cp->cs.nocolor)) {
  973.     if (cp->WritePtr != cp->myWindow) rmPix(cp->WritePtr, cp->mapptr);
  974.     if (cp->PictPtr != 0) rmPix(cp->PictPtr, cp->pmapptr);
  975.     }
  976. else {
  977.     if (cp->WritePtr != cp->myWindow) ClosePort(cp->WritePtr);
  978.     if (cp->mapptr != 0) DisposPtr(cp->mapptr);
  979.     if (cp->PictPtr != 0) ClosePort(cp->PictPtr);
  980.     if (cp->pmapptr != 0) DisposPtr(cp->pmapptr);
  981.     }
  982. cp->PictPtr = 0;
  983. cp->textmap = 0;
  984. cp->mapptr = cp->pmapptr = 0;
  985. cp->textsize = cp->pictsize = 0;
  986. }
  987.  
  988. void restorectab()
  989. {
  990. static unsigned char * RomMapInsert = (unsigned char *)0xb9e;
  991. static unsigned char * TmpResLoad = (unsigned char *)0xb9f;
  992. PaletteHandle oldpalette, fixpalette;
  993. short pixdepth, colorcnt;
  994. GDHandle currGD;
  995. PixMapHandle currPM;
  996. CTabHandle dflttab;
  997. cnr *cp;
  998. short i;
  999. char foundwindow;
  1000.  
  1001.                     /* attempt to restore default color table */
  1002. if (!colormac) return;        /* done if no color */
  1003. if (syslevel > 6) return;    /* return if system handles color without our help */
  1004.  
  1005.                             /* look for a window we can use (should only be 1) */
  1006. foundwindow = 0;
  1007. for (i=0; i < MAXSESSIONS; i++) {
  1008.     cp = cplist[i];
  1009.     if (cp != 0) {
  1010.         if (cp->myWindow != 0) {
  1011.             foundwindow = 1;
  1012.             break;
  1013.             }
  1014.         }
  1015.     }
  1016.  
  1017. if (!foundwindow) return;    /* return if no window */
  1018.  
  1019. currGD = GetMainDevice();        /* get pixel depth of menu device */
  1020. currPM = (*currGD)->gdPMap;
  1021. pixdepth = (*currPM)->pixelSize;
  1022.  
  1023. colorcnt = 2 << (pixdepth-1);        /* compute number of colors */
  1024.  
  1025.                             /* get default color table for pixel depth */
  1026. (*RomMapInsert) = 0xff;            /* include ROM in search */
  1027. (*TmpResLoad) = 0;                /* shouldn't need to load into memory */
  1028. dflttab = (CTabHandle)GetResource('clut', pixdepth);
  1029. if (dflttab == 0) return;        /* give up if no resource */
  1030.  
  1031.                             /* use palette to set colors */
  1032. fixpalette = NewPalette(colorcnt+1, dflttab, pmTolerant, 0);
  1033. if (fixpalette == 0) return;            /* give up if can't get a palette */
  1034. oldpalette = GetPalette(cp->myWindow);
  1035. SetPalette(cp->myWindow, fixpalette, 0);    /* use new palette */
  1036. ActivatePalette(cp->myWindow);
  1037. if (oldpalette != 0) {
  1038.     DisposePalette(oldpalette);            /* free previous palette */
  1039.     }
  1040. }
  1041.  
  1042. OSErr newmode(char mode, char create, cnr *cp)
  1043.             /* mode: 0 = normal; 1 = alternate */
  1044.             /* create: 0 = change size; 1 = create window */
  1045. {            
  1046. short wproc;
  1047. BitMap PictMap;
  1048. BitMap WriteMap;
  1049. Size mapsize, pmapsize;
  1050. Ptr temp;
  1051. WStateData * wsptr;
  1052. short logrows, logcols;
  1053. short old_hpix, old_vpix;
  1054. Point p, q;
  1055. Rect r;
  1056. RGBColor rgbtemp;
  1057. PixMapHandle currPM;
  1058. short adj;
  1059. unsigned char cposstr[16];
  1060. unsigned char newwtitle[256];
  1061.  
  1062. /* calculate buffer size variables (logical rows and columns) */
  1063. if (mode == 0) {
  1064.     logrows = 24;
  1065.     logcols = 80;
  1066.     }
  1067. else {
  1068.     logrows = cp->cs.altrows;
  1069.     logcols = cp->cs.altcols;
  1070.     }
  1071.  
  1072. /* update the 3270 buffer variables */
  1073. cp->maxcnt = logrows * logcols;
  1074. cp->maxoff = cp->maxcnt - 1;
  1075. cp->scrvoff = logrows - 1;
  1076. cp->scrhsize = logcols;
  1077. cp->scrhoff = cp->scrhsize - 1;
  1078.                                         /* keep cursor within text area */
  1079. if (cp->curadr > cp->maxoff) cp->curadr = cp->maxoff;
  1080.  
  1081. /* calculate window size variables */
  1082. cp->cur_mode = mode;
  1083. if (cp->cur_mode == 1) {
  1084.     cp->cur_rows = cp->cs.altrows;
  1085.     cp->cur_cols = cp->cs.altcols;
  1086.     cp->cur_ptsize = cp->cs.altptsize;
  1087.     }
  1088. else {
  1089.     cp->cur_rows = 24;
  1090.     cp->cur_cols = 80;
  1091.     cp->cur_ptsize = cp->cs.dfltptsize;
  1092.     }
  1093.     
  1094.                             /* save current window dimensions */
  1095. old_hpix = cp->hpixsize;
  1096. old_vpix = cp->vpixsize;
  1097.                             /* set constants for new screen */
  1098. setmode(cp->cur_rows, cp->cur_cols, cp->cur_ptsize, cp->cs.windmax, cp);
  1099.  
  1100.                             /* return if no window needed by api */
  1101. if (cp->apihide) return(0);
  1102.  
  1103.                             /* return if change size call and no window */
  1104.                             /* (currently shouldn't happen) */
  1105. if ((cp->myWindow == 0) && (create == 0)) return(0);
  1106.  
  1107. /* return if the current window is already the proper size */
  1108. if (cp->myWindow != 0) {
  1109.     if ((old_hpix == cp->hpixsize) && (old_vpix == cp->vpixsize)) {
  1110.         return(0);
  1111.         }
  1112.     }
  1113.  
  1114. if (cp->myWindow != 0) {            /* clean-up old window and bitmaps */
  1115.     if (create) removewindow(cp);
  1116.     else removebitmaps(cp);
  1117.     }
  1118.  
  1119.                             /* keep cursor on screen */
  1120. if (cp->curadr > cp->maxoff) cp->curadr = cp->maxoff;
  1121.  
  1122.                             /* change cursor if white needed */
  1123. if ((!cp->cs.invertbw) && colormac && (!cp->cs.nocolor)) cp->curnum += 2;
  1124.  
  1125. defcursor(0, 0, cp);        /* define er rectangle for screen cursor */
  1126.  
  1127.                             /* define window rectangle */
  1128. if (smallscreen) {
  1129.     cp->pRect.top = (screenRect.bottom-screenRect.top-cp->vpixsize)/2 + 9;
  1130.     }
  1131. else {
  1132.     cp->pRect.top = (screenRect.bottom-screenRect.top-cp->vpixsize)/2 + 19;
  1133.     }
  1134. if ((cp->pRect.top < 38) && (!smallscreen)) {
  1135.     cp->pRect.top = 38;
  1136.     }
  1137. cp->pRect.left = (screenRect.right-screenRect.left-cp->hpixsize)/2 - 1;
  1138. if (cp->pRect.left < 1) {
  1139.     cp->pRect.left = 1;
  1140.     }
  1141. cp->pRect.bottom = cp->pRect.top + cp->vpixsize;
  1142. cp->pRect.right = cp->pRect.left + cp->hpixsize;
  1143.  
  1144. cp->sizeRect.top = 25;
  1145. cp->sizeRect.left = 50;
  1146. cp->sizeRect.bottom = cp->pRect.bottom - cp->pRect.top + 1;
  1147. cp->sizeRect.right = cp->pRect.right - cp->pRect.left + 1;
  1148.  
  1149. wproc = documentProc + 8;
  1150.  
  1151. if (cp->myWindow == 0) {
  1152.     r = cp->pRect;
  1153.     if (cp->wposok) {    /* use stored window position if available */
  1154.         p.h = cp->cs.windpth;
  1155.         p.v = cp->cs.windptv;
  1156.         r.left = p.h - cp->hpixsize/2 - 1;
  1157.         r.right = r.left + cp->hpixsize + 3;
  1158.         r.top = p.v - cp->vpixsize/2 - 10;
  1159.         r.bottom = r.top + cp->vpixsize + 21;
  1160.         adjmove(&r);
  1161.         r.left += 1;            /* window rectangle -> port rectangle */
  1162.         r.right -= 2;
  1163.         r.top += 19;
  1164.         r.bottom -= 2;
  1165.         }
  1166.     get_sessname(newwtitle, cp);
  1167.     c2pstr(newwtitle);
  1168.     if (colormac && (!cp->cs.nocolor)) {
  1169.         cp->myWindow = NewCWindow(&(cp->wRecord), &r, newwtitle,
  1170.                     true, wproc, (WindowPtr)-1L, true, 0L);
  1171.         if (cp->myWindow == 0L) {
  1172.             return(5);
  1173.             }
  1174.         cp->myPalette = NewPalette(11, 0L, pmCourteous, 0);
  1175.         if (cp->myPalette == 0L) {
  1176.             CloseWindow(cp->myWindow);
  1177.             cp->myWindow = 0;
  1178.             return(6);
  1179.             }
  1180.         SetPalette(cp->myWindow, cp->myPalette, true);
  1181.         fixcolors(cp->myPalette, cp);        /* define colors to use */
  1182.         ActivatePalette(cp->myWindow);
  1183.         }
  1184.     else {
  1185.         cp->myWindow = NewWindow(&(cp->wRecord), &r, newwtitle,
  1186.                     true, wproc, (WindowPtr)-1L, true, 0L);
  1187.         if (cp->myWindow == 0L) {
  1188.             return(7);
  1189.             }
  1190.         }
  1191.     }
  1192. else {
  1193.     SetPort(cp->myWindow);
  1194.     /* change window size, and keep center of window constant */
  1195.     q.h = (cp->myWindow)->portRect.left;    /* save old top left of portRect */
  1196.     q.v = (cp->myWindow)->portRect.top;
  1197.     LocalToGlobal(&q);
  1198.     p.h = ((cp->myWindow)->portRect.right + (cp->myWindow)->portRect.left + 1)/2;
  1199.     p.v = ((cp->myWindow)->portRect.bottom + (cp->myWindow)->portRect.top - 17)/2;
  1200.     LocalToGlobal(&p);        /* global current center */
  1201.     r.left = p.h - cp->hpixsize/2 - 1;
  1202.     r.right = r.left + cp->hpixsize + 3;
  1203.     r.top = p.v - cp->vpixsize/2 - 10;
  1204.     r.bottom = r.top + cp->vpixsize + 21;
  1205.     adjmove(&r);
  1206.     r.left += 1;            /* window rectangle -> port rectangle */
  1207.     r.right -= 2;
  1208.     r.top += 19;
  1209.     r.bottom -= 2;
  1210.     p.h = r.left;
  1211.     p.v = r.top;
  1212.     if (((p.h - q.h) < 0) || ((p.v - q.v) < 0)) {    /* small -> large */
  1213.         MoveWindow(cp->myWindow, p.h, p.v, true);
  1214.         SizeWindow(cp->myWindow, cp->hpixsize, cp->vpixsize, true);
  1215.         }
  1216.     else {                            /* large -> small */
  1217.         SizeWindow(cp->myWindow, cp->hpixsize, cp->vpixsize, true);
  1218.         MoveWindow(cp->myWindow, p.h, p.v, true);
  1219.         }
  1220.     InvalRect(&(cp->gr_rect));
  1221.     InitClip(cp);
  1222.     InvalRect(&(cp->gr_rect));
  1223.  
  1224.     /* restore settings before bitmap allocation */
  1225.     if (colormac && (!cp->cs.nocolor)) {
  1226.         RGBBackColor(&realwhite);
  1227.         ActivatePalette(cp->myWindow);
  1228.         }
  1229.     }
  1230.  
  1231. if (((WindowPeek)cp->myWindow)->dataHandle != 0) {
  1232.     wsptr = (struct WStateData *)(*(((WindowPeek)cp->myWindow)->dataHandle));
  1233.     wsptr->stdState = cp->pRect;
  1234.     if (r == cp->pRect) {
  1235.         adj = (cp->pRect.bottom - cp->pRect.top) / 4;
  1236.         wsptr->userState.top = cp->pRect.top + adj;
  1237.         wsptr->userState.bottom = cp->pRect.bottom - adj;
  1238.         adj = (cp->pRect.right - cp->pRect.left) / 4;
  1239.         wsptr->userState.left = cp->pRect.left + adj;
  1240.         wsptr->userState.right = cp->pRect.right - adj;
  1241.         }
  1242.     else {
  1243.         wsptr->userState = r;
  1244.         }
  1245.     cp->zoomok = 1;
  1246.     }
  1247. else cp->zoomok = 0;
  1248.  
  1249. SetPort(cp->myWindow);
  1250. TextFont(cp->stdfont);
  1251. TextSize(cp->cur_ptsize);
  1252. cp->x_origin = -4;
  1253. cp->y_origin = -6;
  1254. SetOrigin(cp->x_origin, cp->y_origin);
  1255. InitClip(cp);
  1256. cp->grafcursor = GetCursor(cp->curnum);
  1257. if (cp->myWindow == FrontWindow()) {
  1258.     InitCursor();
  1259.     dfltcurs = 1;
  1260.     }
  1261.  
  1262.             /* if color available, save pixel size for this window */
  1263. if (colormac && (!cp->cs.nocolor)) {
  1264.     GetGlobalRect(cp->myWindow, &r);
  1265.     bitmap_gdev = myGetMaxDevice(&r);
  1266.     currPM = (*bitmap_gdev)->gdPMap;
  1267.     cp->pxsize = (*currPM)->pixelSize;
  1268.     }
  1269.  
  1270. cp->textRect.top = cp->scrnRect.top = cp->y_origin;
  1271. cp->statRect.left = cp->textRect.left = cp->scrnRect.left = cp->x_origin;
  1272. cp->statRect.top = cp->textRect.bottom = cp->y_origin + cp->vpixsize - 19;
  1273. cp->statRect.bottom = cp->scrnRect.bottom = cp->statRect.top + 20;
  1274. cp->statRect.right = cp->textRect.right = cp->scrnRect.right =
  1275.     cp->textRect.left + cp->hpixsize;
  1276.  
  1277.                 /* attempt to allocate text bitmap */
  1278. WriteMap.bounds.top = 0;
  1279. WriteMap.bounds.left = 0;
  1280. WriteMap.bounds.bottom = cp->vpixsize;
  1281. WriteMap.bounds.right = cp->hpixsize;
  1282. if (colormac && (!cp->cs.nocolor)) {
  1283.     mkPix(&(cp->WritePort), &(cp->mapptr), &WriteMap.bounds,
  1284.           bitmap_gdev, cp);
  1285.     cp->textsize = cp->pictsize;
  1286.     cp->pictsize = 0;
  1287.     if (cp->mapptr == 0) {
  1288.         cp->WritePtr = cp->myWindow;
  1289.         note_err(mapalrt, cp);
  1290.         }
  1291.     else {
  1292.         cp->WritePtr = &(cp->WritePort);
  1293.         cp->textmap = 1;
  1294.         }
  1295.     SetPort(cp->WritePtr);
  1296.     GetEntryColor(cp->myPalette, RGBback, &rgbtemp);
  1297.     if (cp->WritePtr != cp->myWindow) setgdev(0);
  1298.     RGBBackColor(&rgbtemp);
  1299.     if (cp->WritePtr != cp->myWindow) resetgdev();
  1300.     }
  1301. else {
  1302.     WriteMap.rowBytes = (((cp->hpixsize + 31) >> 5) + 1) << 2;
  1303.     mapsize = WriteMap.bounds.bottom - WriteMap.bounds.top;
  1304.     mapsize = mapsize * WriteMap.rowBytes + 4;
  1305.     cp->textsize = mapsize;
  1306.     cp->mapptr = myNewPtr(mapsize, cp);
  1307.     temp = cp->mapptr;
  1308.     while (((Size)temp%4) != 0) temp++;    /* align on long word */
  1309.     WriteMap.baseAddr = temp;
  1310.     if (WriteMap.baseAddr == 0L) {        /* no screen buffer */
  1311.         cp->WritePtr = cp->myWindow;
  1312.         note_err(mapalrt, cp);
  1313.         }
  1314.     else {
  1315.         cp->WritePtr = &(cp->WritePort);        /* set-up WritePort */
  1316.         cp->textmap = 1;
  1317.         cp->WritePort.portRect = WriteMap.bounds;
  1318.         OpenPort(cp->WritePtr);
  1319.         ClipRect(&(cp->WritePort.portRect));
  1320.         SetPortBits(&(WriteMap));
  1321.         EraseRgn(cp->WritePort.visRgn);
  1322.         TextFont(cp->stdfont);
  1323.         TextSize(cp->cur_ptsize);
  1324.         }
  1325.     }
  1326. if (cp->WritePtr != cp->myWindow) {
  1327.     SetPort(cp->WritePtr);
  1328.      SetOrigin(cp->textRect.left, cp->textRect.top);
  1329.     ClipRect(&(cp->scrnRect));
  1330.     SetPort(cp->myWindow);
  1331.     }
  1332.                                  /* set-up graphics bit map */
  1333. cp->pictRect.top = cp->pictRect.left = 0;
  1334. cp->pictRect.bottom = cp->vpixsize-19;
  1335. cp->pictRect.right = cp->hpixsize;
  1336.  
  1337. cp->PictPtr = &(cp->PictPort);
  1338. if (cp->cs.nographics) {
  1339.     cp->PictPtr = 0;
  1340.     }
  1341. else if ((!colormac) || cp->cs.nocolor) {
  1342.     PictMap.rowBytes = (((cp->hpixsize + 31) >> 5) + 1) << 2;
  1343.     PictMap.bounds = cp->pictRect;
  1344.     pmapsize = PictMap.bounds.bottom - PictMap.bounds.top;
  1345.     pmapsize = pmapsize * PictMap.rowBytes + 4;
  1346.     cp->pictsize = pmapsize;
  1347.     cp->pmapptr = myNewPtr(pmapsize, cp);
  1348.     temp = cp->pmapptr;
  1349.     while (((Size)temp%4) != 0) temp++;    /* align on long word */
  1350.     PictMap.baseAddr = temp;
  1351.     if (PictMap.baseAddr == 0L) {        /* no graphics bitmap */
  1352.         cp->PictPtr = 0;
  1353.         }
  1354.     else {
  1355.                                     /* set-up PictPort */
  1356.         OpenPort(cp->PictPtr);
  1357.         SetPortBits(&(PictMap));
  1358.         PortSize(PictMap.bounds.right, PictMap.bounds.bottom);
  1359.         SetRectRgn(cp->PictPort.visRgn, 0, 0, PictMap.bounds.right,
  1360.                     PictMap.bounds.bottom);
  1361.         ClipRect(&(cp->PictPort.portRect));
  1362.         EraseRect(&(cp->PictPort.portRect));
  1363.         SetOrigin(0, 0);
  1364.         TextFont(cp->stdfont);
  1365.         TextSize(cp->cur_ptsize);
  1366.         }
  1367.     }
  1368. else {
  1369.     mkPix(&(cp->PictPort), &(cp->pmapptr),
  1370.           &(cp->pictRect), bitmap_gdev, cp);
  1371.     if (cp->pmapptr == 0) cp->PictPtr = 0;
  1372.     else {
  1373.         cp->PictPtr = &(cp->PictPort);
  1374.         GetEntryColor(cp->myPalette, RGBback, &rgbtemp);
  1375.         setgdev(0);
  1376.         RGBBackColor(&rgbtemp);
  1377.         resetgdev();
  1378.         }
  1379.     }
  1380.  
  1381. /* define status line cursor postion rectangle */
  1382. cp->cposRect.top = cp->statRect.top;
  1383. cp->cposRect.bottom = cp->statRect.bottom;
  1384. cp->cposRect.left = 315;
  1385. sprintf(cposstr, "%02d/%02d", cp->scrvoff+1, cp->scrhsize);
  1386. TextFont(1);
  1387. TextSize(0);
  1388. c2pstr(cposstr);
  1389. cp->cposRect.right = cp->cposRect.left + StringWidth(cposstr);
  1390. TextFont(cp->stdfont);
  1391. TextSize(cp->cur_ptsize);
  1392.             /* for small screens, adjust cursor position between insert
  1393.                mode symbol and time */
  1394. adj = 10 - cp->hpixsize + 134 + cp->cposRect.right;
  1395. if (adj > 0) {
  1396.     cp->cposRect.left -= adj;
  1397.     cp->cposRect.right -= adj;
  1398.     }
  1399.  
  1400. alignbitmaps(cp);        /* always safe to call */
  1401. invldscr(cp);
  1402. newstat(cp);
  1403. if (cp->cs.digitpfk) (*ScrDmpEnb) = 0;
  1404. else (*ScrDmpEnb) = ScrDmpSav;
  1405. appl_menu();
  1406. return(0);
  1407. }
  1408.  
  1409. OSErr alignbitmaps(cnr *cp)        
  1410.                     /* Adjust bounds of our bitmaps for long word alignment
  1411.                        with the current window position.  Note that our
  1412.                        CopyBits calls copy the leftmost bit of each bitmap
  1413.                        to the leftmost bit of the window. */
  1414.                     /* Non-zero return code indicates no need to redraw
  1415.                        text bitmap */
  1416. {
  1417. short pixeldepth;
  1418. GDHandle currGD;
  1419. PixMapHandle currPM;
  1420. GrafPtr gp;
  1421. Point p;
  1422. Rect r;
  1423. short adj;
  1424. BitMap * mapbits;
  1425.  
  1426. if (cp->drawpict) {
  1427.     cp->pendalign = 1;
  1428.     return(1);
  1429.     }
  1430. else {
  1431.     cp->pendalign = 0;
  1432.     }
  1433.                         /* nothing to do if no bitmaps */
  1434. if ((!cp->textmap) && (cp->PictPtr == 0)) {
  1435.     return(2);
  1436.     }
  1437.  
  1438. if (colormac && (!cp->cs.nocolor)) {
  1439.                         /* if pixel depth has changed, return, since
  1440.                            we will be called for the new bitmap        */
  1441.     GetGlobalRect(cp->myWindow, &r);
  1442.     currGD = myGetMaxDevice(&r);
  1443.     currPM = (*currGD)->gdPMap;
  1444.     if (cp->pxsize != (*currPM)->pixelSize) return(3);
  1445.     if (cp->pxsize > 16) return(4);        /* no adjustment needed */
  1446.     pixeldepth = cp->pxsize;
  1447.     }
  1448. else {
  1449.     pixeldepth = 1;
  1450.     }
  1451.  
  1452. p.h = cp->textRect.left;
  1453. p.v = cp->textRect.top;
  1454. GetPort(&gp);
  1455. SetPort(cp->myWindow);
  1456. LocalToGlobal(&p);
  1457. SetPort(gp);
  1458. getdeskrect(&r);
  1459. p.h = p.h - r.left;        /* ensure a positive value */
  1460. adj = p.h % (32 / pixeldepth);
  1461. if (cp->PictPtr != 0) {
  1462.     if (colormac && (!cp->cs.nocolor)) {
  1463.         mapbits = (BitMap *)(*(PixMapHandle)cp->PictPort.portBits.baseAddr);
  1464.         }
  1465.     else {
  1466.         mapbits = &(cp->PictPort.portBits);
  1467.         }
  1468.     (mapbits->bounds).left = -adj;
  1469.     }
  1470. if (cp->textmap) {
  1471.     if (colormac && (!cp->cs.nocolor)) {
  1472.         mapbits = (BitMap *)(*(PixMapHandle)cp->WritePort.portBits.baseAddr);
  1473.         }
  1474.     else {
  1475.         mapbits = &(cp->WritePort.portBits);
  1476.         }
  1477.     (mapbits->bounds).left = cp->textRect.left - adj;
  1478.     return(0);
  1479.     }
  1480. else {
  1481.     return(5);
  1482.     }
  1483. }
  1484.  
  1485. void setmode(short dsprows, short dspcols, short ptsize, short wmax, cnr *cp)
  1486. {
  1487. short dflthsize, dfltvsize, althsize, altvsize;
  1488.                             /* set constants for desired format */
  1489. switch(ptsize) {
  1490.     case 12:
  1491.                 cp->htxtstrt = 0;
  1492.                 cp->vtxtstrt = 11;
  1493.                 cp->vtxtsize = 16;
  1494.                 cp->htxtsize = 7;
  1495.                 cp->curvsize = 16;
  1496.                 cp->curhsize = 7;
  1497.                 cp->curnum = 20846;
  1498.                 break;
  1499.     default:
  1500.                 cp->htxtstrt = 1;
  1501.                 cp->vtxtstrt = 9;
  1502.                 cp->vtxtsize = 12;
  1503.                 cp->htxtsize = 6;
  1504.                 cp->curvsize = 12;
  1505.                 cp->curhsize = 7;
  1506.                 cp->curnum = 20845;
  1507.                 break;
  1508.     }
  1509. if (wmax) {
  1510.     if (cp->cs.dfltptsize == 9) {
  1511.         dflthsize = 80 * 6 + 10;
  1512.         dfltvsize = 24 * 12 + 26;
  1513.         }
  1514.     else {
  1515.         dflthsize = 80 * 7 + 10;
  1516.         dfltvsize = 24 * 16 + 26;
  1517.         }
  1518.     if (cp->cs.altptsize == 9) {
  1519.         althsize = cp->cs.altcols * 6 + 10;
  1520.         altvsize = cp->cs.altrows * 12 + 26;
  1521.         }
  1522.     else {
  1523.         althsize = cp->cs.altcols * 7 + 10;
  1524.         altvsize = cp->cs.altrows * 16 + 26;
  1525.         }
  1526.     if (dflthsize > althsize) {
  1527.         cp->hpixsize = dflthsize;
  1528.         }
  1529.     else {
  1530.         cp->hpixsize = althsize;
  1531.         }
  1532.     if (dfltvsize > altvsize) {
  1533.         cp->vpixsize = dfltvsize;
  1534.         }
  1535.     else {
  1536.         cp->vpixsize = altvsize;
  1537.         }
  1538.     }
  1539. else {
  1540.     cp->hpixsize = dspcols * cp->htxtsize + 10;
  1541.     cp->vpixsize = dsprows * cp->vtxtsize + 26;
  1542.     }
  1543. }
  1544.  
  1545. void newdepth(cnr *cp)
  1546. {            
  1547.             /* re-allocate bitmaps for new pixel depth */
  1548.             /* (Macs with color QuickDraw only)        */
  1549. PixMapHandle currPM;
  1550. Rect r;
  1551. BitMap WriteMap;
  1552. RGBColor rgbtemp;
  1553. GrafPtr gp;
  1554.  
  1555. GetPort(&gp);
  1556.  
  1557. /* clean-up current bitmaps */
  1558. if (cp->WritePtr != cp->myWindow) rmPix(cp->WritePtr, cp->mapptr);
  1559. if (cp->PictPtr != 0) rmPix(cp->PictPtr, cp->pmapptr);
  1560. cp->mapptr = cp->pmapptr = 0;
  1561. cp->textmap = 0;
  1562.  
  1563. /* save new pixel size */
  1564. GetGlobalRect(cp->myWindow, &r);
  1565. bitmap_gdev = myGetMaxDevice(&r);
  1566. currPM = (*bitmap_gdev)->gdPMap;
  1567. cp->pxsize = (*currPM)->pixelSize;
  1568.  
  1569. /* restore settings before bitmap allocation */
  1570. SetPort(cp->myWindow);
  1571. RGBBackColor(&realwhite);
  1572.  
  1573. /* Get color table updated for colors we want */
  1574. ActivatePalette(cp->myWindow);
  1575.  
  1576.                 /* attempt to allocate text bitmap */
  1577. WriteMap.bounds.top = 0;
  1578. WriteMap.bounds.left = 0;
  1579. WriteMap.bounds.bottom = cp->vpixsize;
  1580. WriteMap.bounds.right = cp->hpixsize;
  1581. mkPix(&(cp->WritePort), &(cp->mapptr),
  1582.       &(WriteMap.bounds), bitmap_gdev, cp);
  1583. cp->textsize = cp->pictsize;
  1584. cp->pictsize = 0;
  1585. if (cp->mapptr == 0) {
  1586.     cp->WritePtr = cp->myWindow;
  1587.     note_err(mapalrt, cp);
  1588.     }
  1589. else {
  1590.     cp->WritePtr = &(cp->WritePort);
  1591.     cp->textmap = 1;
  1592.     }
  1593. SetPort(cp->WritePtr);
  1594. GetEntryColor(cp->myPalette, RGBback, &rgbtemp);
  1595. if (cp->WritePtr != cp->myWindow) {
  1596.     setgdev(0);
  1597.     RGBBackColor(&rgbtemp);
  1598.     resetgdev();
  1599.      SetOrigin(cp->textRect.left, cp->textRect.top);
  1600.     ClipRect(&(cp->scrnRect));
  1601.     }
  1602. else RGBBackColor(&rgbtemp);
  1603.                                  /* set-up graphics bit map */
  1604. cp->pictRect.top = cp->pictRect.left = 0;
  1605. cp->pictRect.bottom = cp->vpixsize-19;
  1606. cp->pictRect.right = cp->hpixsize;
  1607.  
  1608. cp->PictPtr = &(cp->PictPort);
  1609.                                 /* set-up PictPort */
  1610. if (cp->cs.nographics) {
  1611.     cp->PictPtr = 0;
  1612.     }
  1613. else {
  1614.     mkPix(&(cp->PictPort), &(cp->pmapptr),
  1615.           &(cp->pictRect), bitmap_gdev, cp);
  1616.     if (cp->pmapptr == 0) cp->PictPtr = 0;
  1617.     else {
  1618.         setgdev(0);
  1619.         cp->PictPtr = &(cp->PictPort);
  1620.         GetEntryColor(cp->myPalette, RGBback, &rgbtemp);
  1621.         RGBBackColor(&rgbtemp);
  1622.         resetgdev();
  1623.         }
  1624.     }
  1625. SetPort(gp);
  1626. alignbitmaps(cp);
  1627. invldscr(cp);
  1628. newstat(cp);
  1629. justGrowIcon(0, cp);
  1630. }
  1631.  
  1632. void ioend(void)                /* close all active drivers */
  1633. {
  1634. if (haveserial) ser_end();
  1635. if (havesa) sa_end();
  1636. if (havetcp) tcp_end();
  1637. }
  1638.  
  1639. void macend(void)
  1640. {
  1641. short i;
  1642. cnr *cp;
  1643.  
  1644.                 /* clean-up connections */
  1645. for (i=0; i < MAXSESSIONS; i++) {
  1646.     cp = cplist[i];
  1647.     if (cp != 0) {
  1648.         sessionlgout(0, cp);
  1649.         }
  1650.     }
  1651.  
  1652. (*ScrDmpEnb) = ScrDmpSav;    /* restore original byte */
  1653.  
  1654.                             /* clean-up printing */
  1655. if (prtinit) PrClose();
  1656. if (hPrint != 0) DisposHandle((Handle)hPrint);
  1657.  
  1658.                             /* clean-up FTP storage */
  1659. if (DirTree != 0) DisposPtr((Ptr)DirTree);
  1660. if (mungbuf != 0) DisposPtr(mungbuf);
  1661.  
  1662.                             /* clean-up scrap */
  1663. removescrap();
  1664.  
  1665.                             /* clean-up async sound */
  1666. if (sndactive) {
  1667.     SndDisposeChannel(scp, true);
  1668.     }
  1669. if (scp != 0) {
  1670.     DisposPtr((Ptr)scp);
  1671.     }
  1672.                             /* clean-up work region */
  1673. if (temprgn != 0) DisposeRgn(temprgn);
  1674.  
  1675.                             /* clean-up notification manager queue */
  1676. if (notifyavail) {
  1677.     for (i=0; i < NMRNUM; i++) {
  1678.         if (myNMR[i]->qelem.nmRefCon != 0) {
  1679.             NMRemove(&(myNMR[i])->qelem);
  1680.             }
  1681.         }
  1682.     DisposPtr((Ptr)(myNMR[0]));
  1683.     }
  1684.  
  1685.                             /* clean-up API */
  1686. apideregister(0, 0);
  1687.  
  1688. if (ppcavail) {
  1689.     endparamblocks();
  1690.     endclientrecs();
  1691.     enddatablocks();
  1692.     }
  1693. if (rcvMessage != 0) DisposHandle(rcvMessage);
  1694. if (sndMessage != 0) DisposHandle(sndMessage);
  1695. }                        
  1696.  
  1697. void hndmac(void)
  1698. {
  1699. register short code;
  1700. register unsigned short i, w, h, conn;
  1701. register long l;
  1702. static unsigned long * Ticks = (unsigned long *)0x16a;
  1703. static unsigned long * DoubleTime = (unsigned long *)0x2f0;
  1704. static unsigned long clklimit = 0;
  1705. static unsigned long limit = 0;
  1706. GrafPtr gp;
  1707. WindowPtr whichWindow;
  1708. Point pt;
  1709. OSErr rc;
  1710. char background, usenull;
  1711. unsigned char selflag, shiftflag; 
  1712. unsigned char optionflag, commandflag, doubleflag;
  1713. static short downloc = 0;
  1714. static short uploc = 0;
  1715. static short oldloc = 0;
  1716. short moveloc, newloc;
  1717. static unsigned long downtime = 0;
  1718. static unsigned long uptime = 0;
  1719. unsigned short x, y;
  1720. Point dipoint;
  1721. cnr *cp;
  1722.  
  1723.                             /* I/O which must happen often */
  1724. if (haveserial) serevent();
  1725. if (havesa) saevent();
  1726. if (havetcp) tcpevent();
  1727.     
  1728. if (sndactive == 2) {
  1729.     SndDisposeChannel(scp, true);
  1730.     sndactive = 0;
  1731.     }
  1732.     
  1733.                             /* during FTP, take all we can get */
  1734. background = mf_bgrnd && !(ftpcopen || ftplopen);
  1735.  
  1736. usenull = 1;                /* initially will do null processing */
  1737.                                 
  1738. if (!background) {            /* don't do non-essential things too often */
  1739.                             /* when running in the foreground */
  1740.     if (limit >= (*Ticks)) usenull = 0;
  1741.     else limit = (*Ticks) + 4;        /* set time for next null handling */
  1742.     }
  1743.  
  1744.                     /* set sw_bgrnd to 2 if next GNE call will suspend us */
  1745. if (sw_bgrnd == 1) sw_bgrnd = 2;
  1746. if (background) {
  1747.      rc = WaitNextEvent(everyEvent, &myEvent, 4L, 0L);
  1748.      }
  1749. else {
  1750.     rc = GetNextEvent(everyEvent, &myEvent);
  1751.     }
  1752. if ((rc == 0) && usenull)        /* FALSE from GNE */
  1753.     switch(myEvent.what) {
  1754.         case nullEvent:
  1755.                 for (conn = 0; conn < MAXSESSIONS; conn++) {
  1756.                     cp = cplist[conn];
  1757.                     if (cp != 0) {
  1758.                         if (cp->myWindow != 0) {
  1759.                             if (clklimit < (*Ticks)) {        /* clock updating */
  1760.                                 newstat(cp);
  1761.                                 }
  1762.                             if (!mf_bgrnd) {
  1763.                                 if (FrontWindow() == cp->myWindow) {
  1764.                                     /* handle cursor setting */
  1765.                                     GetPort(&gp);
  1766.                                     SetPort(cp->myWindow);
  1767.                                     GetMouse(&pt);
  1768.                                     SetPort(gp);
  1769.                                     i = (PtInRgn(pt, (cp->myWindow)->visRgn) == 0);
  1770.                                     if (!i) i = (PtInRect(pt, &(cp->gr_rect)) != 0);
  1771.                                     if (dfltcurs != i) {
  1772.                                         if (i) SetCursor(normcurs);
  1773.                                         else SetCursor(*(cp->grafcursor));
  1774.                                         dfltcurs = i;
  1775.                                         }
  1776.                                     }
  1777.                                 /* check for color updating */
  1778.                                 if (colormac && (!cp->cs.nocolor)) {
  1779.                                     chkpx(cp);
  1780.                                     if (newCTab(cp)) {
  1781.                                         ActivatePalette(cp->myWindow);
  1782.                                         if (updCTab(cp)) {
  1783.                                             newbackcolor(cp);
  1784.                                             invldscr(cp);
  1785.                                             newstat(cp);
  1786.                                             justGrowIcon(0, cp);
  1787.                                             }
  1788.                                         }
  1789.                                     }
  1790.                                 }
  1791.                             }
  1792.                         }
  1793.                     }
  1794.                 if (clklimit < (*Ticks)) {        /* clock updating limit */
  1795.                     clklimit = (*Ticks) + 600;
  1796.                     }
  1797.                 if (!mf_bgrnd) {
  1798.                     myStask();
  1799.                     SystemTask();            /* run DAs, etc. */
  1800.                     }
  1801.                 if (ppcavail) {            /* check if allocations needed */
  1802.                     addparamblocks();
  1803.                     addclientrecs();
  1804.                     adddatablocks();
  1805.                     }
  1806.                 apinewmsg();            /* check for API event */
  1807.                 break;
  1808.         default:
  1809.                 return;
  1810.         }
  1811. else if (rc != 0) switch(myEvent.what) {        /* true from GNE */
  1812.     case mouseDown:
  1813.         code = FindWindow(myEvent.where, &whichWindow);
  1814.         switch (code) {
  1815.         case inMenuBar:
  1816.             menu_upd();
  1817.             docommand(MenuSelect(myEvent.where),
  1818.                       (myEvent.modifiers & shiftKey) != 0);
  1819.             break;
  1820.         case inSysWindow:
  1821.             SystemClick(&myEvent, whichWindow);
  1822.             break;
  1823.         case inDrag:
  1824.             if (whichWindow == FrontWindow()) {
  1825.                 DragWindow(whichWindow, myEvent.where,
  1826.                             &dragRect);
  1827.                 if (mywindow(whichWindow, &cp)) {
  1828.                     rc = alignbitmaps(cp);
  1829.                     if (rc == 0) {
  1830.                         invldscr(cp);
  1831.                         newstat(cp);
  1832.                         }
  1833.                     }
  1834.                 }
  1835.             else {
  1836.                 SelectWindow(whichWindow);
  1837.                 }
  1838.             break;
  1839.         case inGoAway:
  1840.             if (myxfwindow(whichWindow, &cp)) {
  1841.                 if (TrackGoAway(whichWindow, myEvent.where))
  1842.                     cp->kabort = 1;
  1843.                 break;
  1844.                 }
  1845.             if (mywindow(whichWindow, &cp))
  1846.                 if (TrackGoAway(whichWindow, myEvent.where))
  1847.                     if (wants_to_quit(cp)) {
  1848.                         if (!(cp->serflg && (cp->connstate <= 1))) {
  1849.                             closeresponse(closeUser, cp);
  1850.                             }    
  1851.                         if (cp->serflg) serlgout(0, cp);
  1852.                         else if (cp->tcpflg) tcplgout(0, cp);
  1853.                         else salgout(0, cp);
  1854.                         }
  1855.             break;
  1856.         case inGrow:
  1857.             if (whichWindow == FrontWindow()) {
  1858.                 GetPort(&gp);
  1859.                 SetPort(whichWindow);
  1860.                 if (mywindow(whichWindow, &cp)) {
  1861.                     SetClip(cp->cliprgn);
  1862.                     }
  1863.                 l = GrowWindow(whichWindow, myEvent.where,
  1864.                             &(cp->sizeRect));
  1865.                 h = l >> 16;
  1866.                 w = l & 0x0000ffffL;
  1867.                 SizeWindow(whichWindow, w, h, true);
  1868.                 if (mywindow(whichWindow, &cp)) {
  1869.                     InvalRect(&(cp->gr_rect));
  1870.                     InitClip(cp);
  1871.                     InvalRect(&(cp->gr_rect));
  1872.                     }
  1873.                 if (myxfwindow(whichWindow, &cp)) {
  1874.                     EraseRect(&(whichWindow->portRect));
  1875.                     InvalRect(&(whichWindow->portRect));
  1876.                     }
  1877.                 SetPort(gp);
  1878.                 }
  1879.             break;
  1880.         case inContent:
  1881.             if (whichWindow != FrontWindow()) {
  1882.                 SelectWindow(whichWindow);
  1883.                 break;
  1884.                 }
  1885.             if (mywindow(whichWindow, &cp)) {
  1886.                 downtime = myEvent.when;
  1887.                 shiftflag = (myEvent.modifiers & shiftKey) != 0;
  1888.                 optionflag = (myEvent.modifiers & optionKey) != 0;
  1889.                 commandflag = (myEvent.modifiers & cmdKey) != 0;
  1890.                 GetPort(&gp);
  1891.                 SetPort(whichWindow);
  1892.                 GlobalToLocal(&myEvent.where);
  1893.                     
  1894.                 /* calculate location for cursor movement (moveloc) */
  1895.                 x = (myEvent.where.h-2+cp->htxtstrt)/cp->htxtsize;
  1896.                 y = myEvent.where.v/cp->vtxtsize;
  1897.                 if (x < 0) x = 0;
  1898.                 if (x > cp->scrhoff) x = cp->scrhoff;
  1899.                 if (y < 0) y = 0;
  1900.                 if (y > cp->scrvoff) y = cp->scrvoff;
  1901.                 moveloc = (y*cp->scrhsize) + x;
  1902.  
  1903.                 /* check if mouse down is close enough in time and     */
  1904.                 /* location to be a valid double click                 */
  1905.                 doubleflag = ((downtime - uptime) <= (*DoubleTime)) &&
  1906.                              (moveloc == uploc);
  1907.                 uptime = 0;
  1908.                                 
  1909.                 /* calculate location for selection (downloc) */
  1910.                 x = (myEvent.where.h-2+cp->htxtstrt)/cp->htxtsize;
  1911.                 y = myEvent.where.v/cp->vtxtsize;
  1912.                 if (x < 0) x = 0;
  1913.                 if (x > cp->scrhoff) {
  1914.                     if (optionflag) x = cp->scrhoff;
  1915.                     else x = cp->scrhsize;
  1916.                     }
  1917.                 if (y < 0) y = 0;
  1918.                 if (y > cp->scrvoff) {
  1919.                     if (optionflag) downloc = (cp->scrvoff*cp->scrhsize) + x;
  1920.                     else downloc = cp->maxcnt;
  1921.                     }
  1922.                 else downloc = (y*cp->scrhsize) + x;
  1923.                     
  1924.                 newloc = downloc;
  1925.                 selflag = 0;
  1926.                 downtime = *Ticks;
  1927.                 while (StillDown()) {
  1928.                     GetMouse(&pt);
  1929.                     x = (pt.h-2+cp->htxtstrt)/cp->htxtsize;
  1930.                     y = pt.v/cp->vtxtsize;
  1931.                     if (x < 0) x = 0;
  1932.                     if (x > cp->scrhoff) {
  1933.                         if (optionflag) x = cp->scrhoff;
  1934.                         else x = cp->scrhsize;
  1935.                         }
  1936.                     if (y < 0) y = 0;
  1937.                     if (y > cp->scrvoff) {
  1938.                         if (optionflag) newloc = (cp->scrvoff*cp->scrhsize) + x;
  1939.                         else newloc = cp->maxcnt;
  1940.                         }
  1941.                     else newloc = (y*cp->scrhsize) + x;
  1942.                     if ((selflag == 0) && (newloc != downloc)) { /* sel init */
  1943.                         if (optionflag == 0) {
  1944.                             if (shiftflag) {
  1945.                                 checksel(cp);
  1946.                                 if (cp->textsel) addsel(&downloc, cp); /* reset downloc */
  1947.                                 }
  1948.                             arrowcursor();
  1949.                             }
  1950.                         selflag = 1;
  1951.                         mousesel(0, downloc, doubleflag, cp);
  1952.                         }
  1953.                     if (selflag) {
  1954.                         if (optionflag) mousesel(1, newloc, doubleflag, cp);    
  1955.                         else mousesel(2, newloc, doubleflag, cp);
  1956.                         }
  1957.                     if (cp->tcpflg) myStask();
  1958.                     }
  1959.                 downtime = (*Ticks) - downtime;
  1960.                 SetPort(gp);
  1961.                 if (selflag) mousesel(3, 0, doubleflag, cp);    /* termination */
  1962.                 if (selflag &&         /* don't use singe position selection */
  1963.                     ((newloc - downloc > 1) || 
  1964.                      (newloc - downloc < -1) ||
  1965.                      (downtime > 60) ||
  1966.                      doubleflag )) {
  1967.                     if (newloc != downloc) {
  1968.                         if (optionflag) {
  1969.                             if (!shiftflag) resetsel(cp);
  1970.                             setrectsel(newloc, downloc, cp);
  1971.                             if (doubleflag) addfieldsel(cp);
  1972.                             }
  1973.                         else {
  1974.                             if (commandflag == 0) resetsel(cp);
  1975.                             if (doubleflag) wordadj(&downloc, &newloc, 1, cp);
  1976.                             settextsel(newloc, downloc, commandflag, cp);
  1977.                             }
  1978.                         }
  1979.                     if (cp->serflg && (cp->connstate == 1)) break;
  1980.                     if (cp->tcpflg && (!(cp->logon))) break;
  1981.                     if (doubleflag) {
  1982.                         cp->curadr = oldloc;
  1983.                         newcur(cp);
  1984.                         }
  1985.                     break;
  1986.                     }
  1987.                 if (((cp->atrbuff)[downloc] & 0x0020) && (!shiftflag)
  1988.                     && (!doubleflag)) {
  1989.                     resetsel(cp);
  1990.                     break;
  1991.                     }
  1992.                 if (cp->serflg && (cp->connstate == 1)) break;
  1993.                 if (cp->tcpflg && (!(cp->logon))) break;
  1994.                 oldloc = cp->curadr;
  1995.                 cp->curadr = moveloc;
  1996.                 newcur(cp);
  1997.                 if (doubleflag) {
  1998.                     if (cp->kblock || (cp->vmxbgn && (!(cp->vmxsub)))) beep(cp);
  1999.                     else clickattn(cp->cs.mousepf, cp);
  2000.                     }
  2001.                 }
  2002.             break;
  2003.  
  2004.         case inZoomIn:
  2005.         case inZoomOut:
  2006.             if (TrackBox(whichWindow, myEvent.where, code))
  2007.                 dozoom(whichWindow, code);
  2008.             break;
  2009.  
  2010.         default:
  2011.             break;
  2012.         }
  2013.         break;
  2014.  
  2015.     case mouseUp:
  2016.         if (FindWindow(myEvent.where, &whichWindow) !=
  2017.             inContent) break;
  2018.         if (mywindow(whichWindow, &cp)) {
  2019.             if (whichWindow != FrontWindow()) break;
  2020.             uptime = myEvent.when;
  2021.             GetPort(&gp);
  2022.             SetPort(whichWindow);
  2023.             GlobalToLocal(&myEvent.where);
  2024.             SetPort(gp);
  2025.             x = (myEvent.where.h-2+cp->htxtstrt)/cp->htxtsize;
  2026.             y = myEvent.where.v/cp->vtxtsize;
  2027.             if (x < 0) x = 0;
  2028.             if (x > cp->scrhoff) x = cp->scrhoff;
  2029.             if (y < 0) y = 0;
  2030.             if (y > cp->scrvoff) y = cp->scrvoff;
  2031.             uploc = (y*cp->scrhsize) + x;
  2032.             }
  2033.         break;
  2034.  
  2035.     case keyDown:
  2036.     case autoKey:
  2037.         kbdevent(&myEvent);
  2038.         break;
  2039.  
  2040.     case activateEvt:
  2041.         dfltcurs = 2;            /* force cursor to be set */
  2042.         if (myEvent.modifiers & activeFlag) {    /* activate event */
  2043.             if (da_menu != 0) {
  2044.                 da_menu = 0;
  2045.                 SetItem(myMenus[1], 19, "\pQuit");
  2046.                 }
  2047.             }
  2048.         else {                                    /* deactivate event */
  2049.             if (da_menu == 0) {
  2050.                 da_menu = 1;
  2051.                 SetItem(myMenus[1], 19, "\pClose");
  2052.                 }
  2053.             if (mywindow((struct GrafPort *)myEvent.message, &cp)) {
  2054.                     arrowcursor();
  2055.                     }
  2056.             }
  2057.         appl_menu();
  2058.         if (mywindow((struct GrafPort *)myEvent.message, &cp)) {
  2059.             if (myEvent.modifiers & activeFlag) {    /* activate event */
  2060.                 if (colormac && (!cp->cs.nocolor)) {
  2061.                     updCTab(cp);
  2062.                     newbackcolor(cp);
  2063.                     invldscr(cp);
  2064.                     cp->cs.stat_time += 8;
  2065.                     newstat(cp);
  2066.                     chkpx(cp);
  2067.                     }
  2068.                 if (cp->cs.digitpfk) (*ScrDmpEnb) = 0;
  2069.                 else (*ScrDmpEnb) = ScrDmpSav;
  2070.                 }
  2071.             justGrowIcon(0, cp);    /* activate or deactivate */
  2072.             }
  2073.         else if (myxfwindow((struct GrafPort *)myEvent.message, &cp)) {
  2074.             xfGrowIcon(cp);
  2075.             }
  2076.         break;
  2077.  
  2078.     case updateEvt:
  2079.         updevent((GrafPtr)myEvent.message);
  2080.         break;
  2081.  
  2082.     case app4Evt:        /* probably switcher */
  2083.         if ((myEvent.message & 0xff000000) != 0x01000000)
  2084.             break;    /* not switcher event */
  2085.         else if (myEvent.message & 0x00000001) sw_resume(myEvent.message);
  2086.                 else sw_suspend(myEvent.message);
  2087.         break;
  2088.  
  2089.     case diskEvt:    /* if mount failed, put up disk init dialog */
  2090.         if ((myEvent.message & 0xffff0000) != 0) {
  2091.             dipoint.h = kDILeft;
  2092.             dipoint.v = kDITop;
  2093.             DIBadMount(dipoint, myEvent.message);
  2094.             }
  2095.         break;
  2096.  
  2097.     default:    break;
  2098.     }
  2099. }
  2100.  
  2101. void kbdevent(EventRecord *myEvent)
  2102. {
  2103. cnr *cp;
  2104. unsigned char linemode, asciicode;
  2105. unsigned short h, i, j, k, hexcount;
  2106. hexmap *hm;
  2107. Size s;
  2108. char tcpecho;
  2109. long mResult;
  2110. short theMenu;
  2111.  
  2112. if (myEvent->what == keyDown) {
  2113.                                 /* check for special user */
  2114.     if ((myEvent->modifiers & 0x0f00) == 0x0f00) {
  2115.         if (((myEvent->message & 0x7f00) >> 8) == 0x24) {
  2116.             if (specmenu == 0) {
  2117.                 AppendMenu(configMenu, "\pSpecial...");
  2118.                 specmenu = 1;
  2119.                 }
  2120.             return;
  2121.             }
  2122.         }
  2123.     }
  2124.  
  2125. cp = front_cp();
  2126.  
  2127. if (cp == 0) {        /* if no session window, could be a menu key */
  2128.     if ((myEvent->modifiers & cmdKey) && (myEvent->what == keyDown)) {
  2129.         mResult = MenuKey(myEvent->message & 0xff);
  2130.         theMenu = mResult >> 16;
  2131.         if (theMenu != 0) {
  2132.             menu_upd();
  2133.             docommand(mResult, (myEvent->modifiers & shiftKey) != 0);
  2134.             }
  2135.         }
  2136.     return;
  2137.     }
  2138.  
  2139.                 /* for a line mode connection, determine the */
  2140.                 /* ASCII code to use for the key             */
  2141. asciicode = 0xff;
  2142. linemode = (cp->serflg && (cp->connstate ==1)) ||
  2143.            (cp->tcpflg && (cp->connstate == 4));
  2144.  
  2145. if (linemode) {    
  2146.     asciicode = myEvent->message & 0x7f;
  2147.     if (extkybd) {                /* keyboard with control and ESC keys */
  2148.         if (myEvent->modifiers & 0x1000) {        /* control key */
  2149.             asciicode &= 0x1f;
  2150.             }
  2151.         }
  2152.     else {            /* use command key for control; map ESC if no ESC key */
  2153.         if ((asciicode == 0x60) && (!newkybd)) asciicode = 0x1b;    /* accent -> ESC */
  2154.         if (myEvent->modifiers & 0x100) {
  2155.             if ((asciicode == 0x1b) && (!newkybd)) asciicode = 0x60;
  2156.             else {
  2157.                 if (asciicode == 0x08) asciicode = 0x7f;
  2158.                 else asciicode &= 0x1f;
  2159.                 }
  2160.             }
  2161.         }
  2162.             /* for serial modem connection, finish processing now */
  2163.     if (cp->serflg) {
  2164.         ObscureCursor();
  2165.         if (asciicode == 0x12) {
  2166.             cp->serverflags = 0x01;
  2167.             srvswitch(cp);
  2168.             }
  2169.         else {
  2170.             if (cp->servermode) {
  2171.                 putsrv(&asciicode, 1, 1, cp);
  2172.                 }
  2173.             else {
  2174.                 serout(asciicode);
  2175.                 }
  2176.             }
  2177.         return;
  2178.         }
  2179.     }
  2180.  
  2181. i = (myEvent->message & 0x7f00) >> 8; /* key code */
  2182.             
  2183.                         /* check special serial mode control characters */
  2184. if (cp->serflg && (myEvent->modifiers & cmdKey)) {
  2185.     if (i == 6) {
  2186.         serin(255, 0, cp);    /* cmd-Z */
  2187.         return;
  2188.         }
  2189.     }
  2190.             
  2191.                         /* apply modifiers for keycode test */
  2192. if ((myEvent->modifiers & (cmdKey+shiftKey)) ==
  2193.     (cmdKey+shiftKey)) i += 384;
  2194. else if (myEvent->modifiers & cmdKey) i += 256;
  2195. else if (myEvent->modifiers & optionKey) i += 512;
  2196. else if (myEvent->modifiers & shiftKey) i += 128;
  2197.                         /* get array entry */
  2198. k = (*(cp->kb_handle))[i];
  2199.                         /* if no keycode entry, try ASCII code */
  2200. if (k == 0) {
  2201.     i = myEvent->message & 0xff;            /* ASCII code */
  2202.     if ((myEvent->modifiers & (cmdKey+shiftKey)) ==
  2203.         (cmdKey+shiftKey)) i += 768;
  2204.     else if (myEvent->modifiers & cmdKey) i += 512;
  2205.     else if (myEvent->modifiers & optionKey) i += 1024;
  2206.     else if (myEvent->modifiers & shiftKey) i += 256;
  2207.     i += 640;            /* skip over keycode tables */
  2208.                         /* get array entry */
  2209.     k = (*(cp->kb_handle))[i];
  2210.     }
  2211.                         /* for telnet line mode, set k to 0 unless it is */
  2212.                         /* one of the functions we map.                     */
  2213.                         /* Note: the function list must match the list     */
  2214.                         /*       found in "telnet.c".                     */
  2215. if (linemode) {
  2216.     if (k > 142) {            /* for efficiency */
  2217.         k -= 1;
  2218.         switch(k) {
  2219.             case 143:                /* "pf1" function */
  2220.             case 144:                /* "pf2" function */
  2221.             case 145:                /* "pf3" function */
  2222.             case 146:                /* "pf4" function */
  2223.             case 190:                /* "rub-out" function */
  2224.             case 170:                /* "clear" function */
  2225.                         tcpecho = 0;    /* these are never echoed */
  2226.                         break;
  2227.             case 142:                /* "enter" function */
  2228.             case 175:                /* "left" function */
  2229.             case 173:                /* "up" function */
  2230.             case 174:                /* "down" function */
  2231.             case 184:                /* "delete-char" function */
  2232.             case 176:                /* "right" function */
  2233.                         tcpecho = 1;
  2234.                         break;
  2235.             default:
  2236.                         tcpecho = 1;
  2237.                         k = 0;
  2238.                         break;
  2239.             }
  2240.         }
  2241.     else {
  2242.         k = 0;
  2243.         tcpecho = 1;
  2244.         }
  2245.     }
  2246.             
  2247.                         /* if no array entry, check for menu equivalent */
  2248. if (k == 0) {
  2249.     if ((myEvent->modifiers & cmdKey) && (myEvent->what == keyDown)) {
  2250.         mResult = MenuKey(myEvent->message & 0xff);
  2251.         theMenu = mResult >> 16;
  2252.         if (theMenu != 0) {
  2253.             menu_upd();
  2254.             docommand(mResult, (myEvent->modifiers & shiftKey) != 0);
  2255.             return;
  2256.             }
  2257.         }
  2258.     }
  2259.         
  2260.                         /* finish telnet line mode processing */
  2261.                         /* don't call tcpin for efficiency */
  2262. if (linemode) {
  2263.                             /* handle special server mode */
  2264.     if (cp->servermode) {
  2265.         putsrv(&asciicode, 1, 1, cp);
  2266.         return;
  2267.         }
  2268.                             /* send ASCII to host */
  2269.     if (cp->kblock) {            /* check for locked keyboard */
  2270.         beep(cp);
  2271.         return;
  2272.         }
  2273.     if (k == 0) {                /* send character */
  2274.         tcpwrite(&asciicode, 1, cp);
  2275.         }
  2276.     else {                        /* send function sequence */
  2277.         h = (myEvent->modifiers & alphaLock) != 0;
  2278.         tcpkbin(asciicode, k, h, cp);
  2279.         }
  2280.                                 /* echo unless host is doing it */
  2281.     if ((!(cp->hisopts)[TELOPT_ECHO]) && tcpecho) {
  2282.         putscr(&asciicode, 1, 0, cp);
  2283.         }
  2284.     return;
  2285.     }
  2286.  
  2287.                         /* continue with 3270-mode processing */                
  2288. if (k == 0) {                /* ignore unmapped key */
  2289.     return;
  2290.     }
  2291. k -= 1;
  2292.     
  2293. if (myEvent->what == autoKey) {
  2294.     if ((kbtyp[k] & 0x0f) == 2) {
  2295.         return;
  2296.         }
  2297.     }            
  2298.  
  2299. /* check for overriding hex mapping */
  2300. if (k == 254) {
  2301.     /* no typeahead for special hex chars */
  2302.     if (cp->kbqsize > 0) {
  2303.         beep(cp);
  2304.         return;
  2305.         }
  2306.     s = GetHandleSize(cp->kb_handle);
  2307.     if (s > 1920) {
  2308.         hexcount = (s - 1920)/4;
  2309.           hm = (hexmap *)((*(cp->kb_handle)) + 1920);
  2310.         kbstd[k] = 0;
  2311.         for (j=0; j < hexcount; j++) {
  2312.             if (hm->offset == i) {
  2313.                 kbstd[k] = hm->stdchar;
  2314.                 kbapl[k] = hm->aplchar;
  2315.                 break;
  2316.                 }
  2317.             hm++;
  2318.             }
  2319.         if (kbstd[k] == 0) return;
  2320.         }
  2321.     else return;
  2322.     }
  2323.     
  2324. ObscureCursor();
  2325. h = (myEvent->modifiers & alphaLock) != 0;
  2326. if (cp->serflg) serin(k, h, cp);
  2327. else if (cp->tcpflg) tcpin(asciicode, k, h, cp);
  2328. else sain(asciicode, k, h, cp);
  2329. }
  2330.  
  2331. void dozoom(WindowPtr wp, short code)
  2332. {
  2333. GrafPtr gp;
  2334. OSErr rc;
  2335. cnr *cp;
  2336.  
  2337.                         /* be sure this window can zoom */
  2338. if (((WindowPeek)wp)->dataHandle == 0) return;
  2339.  
  2340. GetPort(&gp);
  2341. SetPort(wp);
  2342. if (mywindow(wp, &cp)) SetClip(cp->cliprgn);
  2343. EraseRect(&(wp->portRect));
  2344. ZoomWindow(wp, code, false);
  2345. if (mywindow(wp, &cp)) {
  2346.     InitClip(cp);
  2347.     InvalRect(&(cp->gr_rect));
  2348.     rc = alignbitmaps(cp);
  2349.     if (rc == 0) {
  2350.         invldscr(cp);
  2351.         newstat(cp);
  2352.         }
  2353.     }
  2354. SetPort(gp);
  2355. }
  2356.  
  2357. short zoomstate(cnr *cp)
  2358. {
  2359. Rect r;
  2360. WStateData * wsptr;
  2361.  
  2362. if (cp->myWindow == 0) return(0);    /* return if no window */
  2363.                                 /* be sure my window can zoom */
  2364. if (((WindowPeek)cp->myWindow)->dataHandle == 0) return(0);
  2365.  
  2366.                                 /* convert portRect to global coordinates */
  2367. GetGlobalRect(cp->myWindow, &r);
  2368.                                 /* check for standard vs. user state */
  2369. wsptr = (struct WStateData *)(*(((WindowPeek)cp->myWindow)->dataHandle));
  2370. if ((wsptr->stdState) == r) return(inZoomIn);    /* return code */
  2371. else return(inZoomOut);
  2372. }
  2373.  
  2374. cnr *front_cp(void)            /* return pointer to connection for front window */
  2375. {
  2376. GrafPtr gp;
  2377. short i;
  2378. cnr *cp;
  2379.  
  2380. gp = FrontWindow();
  2381. if (gp == 0) return(0);
  2382. for (i = 0; i < MAXSESSIONS; i++) {
  2383.     cp = cplist[i];
  2384.     if (cp != 0) {
  2385.         if (cp->myWindow == gp) return(cp);
  2386.         if (cp->xdlg && (cp->xdlgptr == gp)) return(cp);
  2387.         }
  2388.     }
  2389. return(0);
  2390. }
  2391.  
  2392. char mywindow(GrafPtr whichWindow, cnr** cpp)
  2393. {
  2394. short i;
  2395. cnr *cp;
  2396.  
  2397. if (whichWindow == 0) return(0);
  2398. for (i=0; i < MAXSESSIONS; i++) {
  2399.     cp = cplist[i];
  2400.     if (cp != 0) {
  2401.         if (cp->myWindow == whichWindow) {
  2402.             *cpp = cp;
  2403.             return(true);
  2404.             }
  2405.         }
  2406.     }
  2407. return(false);
  2408. }
  2409.  
  2410. char myxfwindow(GrafPtr whichWindow, cnr** cpp)
  2411. {
  2412. short i;
  2413. cnr *cp;
  2414.  
  2415. if (whichWindow == 0) return(0);
  2416. for (i=0; i < MAXSESSIONS; i++) {
  2417.     cp = cplist[i];
  2418.     if (cp != 0) {
  2419.         if (cp->xdlg && (whichWindow == cp->xdlgptr)) {
  2420.             *cpp = cp;
  2421.             return(true);
  2422.             }
  2423.         }
  2424.     }
  2425. return(false);
  2426. }
  2427.  
  2428. void chkpx(cnr *cp) 
  2429. {                        /* handle user changing pixel bit depth */
  2430. GDHandle currGD;
  2431. PixMapHandle currPM;
  2432. Rect r;
  2433.  
  2434. if ((!colormac) || cp->cs.nocolor) return;
  2435. GetGlobalRect(cp->myWindow, &r);
  2436. currGD = myGetMaxDevice(&r);
  2437. currPM = (*currGD)->gdPMap;
  2438. if (cp->pxsize == (*currPM)->pixelSize) return;
  2439. newdepth(cp);
  2440. }
  2441.  
  2442. void fixcolors(PaletteHandle p, cnr *cp)
  2443.                     /* fixcolors is called to handle a redefinition of        */
  2444.                     /* one of the "usr" colors.  It updates the specified    */
  2445.                     /* palette and associated window.                        */
  2446. {
  2447. short i, usage;
  2448. RGBColor rgbtemp;
  2449.  
  2450. if (cp->cs.exactcolor) {
  2451.     SetEntryColor(p, RGBblack, &(cp->cs.usrblack));
  2452.     SetEntryColor(p, RGBwhite, &(cp->cs.usrwhite));
  2453.     SetEntryColor(p, RGBback, &(cp->cs.usrback));
  2454.     SetEntryColor(p, RGBgreen, &(cp->cs.usrgreen));
  2455.     SetEntryColor(p, RGBred, &(cp->cs.usrred));
  2456.     SetEntryColor(p, RGBblue, &(cp->cs.usrblue));
  2457.     SetEntryColor(p, RGBpink, &(cp->cs.usrpink));
  2458.     SetEntryColor(p, RGByellow, &(cp->cs.usryellow));
  2459.     SetEntryColor(p, RGBturquoise, &(cp->cs.usrturquoise));
  2460.     SetEntryColor(p, RGBstat, &(cp->cs.usrstat));
  2461.     }
  2462. else {
  2463.     mapcolor(&(cp->cs.usrblack), &rgbtemp, cp);
  2464.     SetEntryColor(p, RGBblack, &rgbtemp);
  2465.     SetEntryColor(p, RGBwhite, &(cp->cs.usrwhite));
  2466.     SetEntryColor(p, RGBback, &(cp->cs.usrback));
  2467.     mapcolor(&(cp->cs.usrgreen), &rgbtemp, cp);
  2468.     SetEntryColor(p, RGBgreen, &rgbtemp);
  2469.     mapcolor(&(cp->cs.usrred), &rgbtemp, cp);
  2470.     SetEntryColor(p, RGBred, &rgbtemp);
  2471.     mapcolor(&(cp->cs.usrblue), &rgbtemp, cp);
  2472.     SetEntryColor(p, RGBblue, &rgbtemp);
  2473.     mapcolor(&(cp->cs.usrpink), &rgbtemp, cp);
  2474.     SetEntryColor(p, RGBpink, &rgbtemp);
  2475.     mapcolor(&(cp->cs.usryellow), &rgbtemp, cp);
  2476.     SetEntryColor(p, RGByellow, &rgbtemp);
  2477.     mapcolor(&(cp->cs.usrturquoise), &rgbtemp, cp);
  2478.     SetEntryColor(p, RGBturquoise, &rgbtemp);
  2479.     mapcolor(&(cp->cs.usrstat), &rgbtemp, cp);
  2480.     SetEntryColor(p, RGBstat, &rgbtemp);
  2481.     }
  2482.  
  2483. if (cp->cs.exactcolor) usage = pmTolerant;
  2484.            else usage = pmCourteous;
  2485. for (i=1; i < 10; i++)
  2486.     SetEntryUsage(p, i, usage, 0);
  2487. }
  2488.  
  2489. void mapcolor(RGBColor *in, RGBColor *out, cnr *cp)
  2490. {
  2491. long l;
  2492. short i;
  2493. RGBColor csave;
  2494.  
  2495. if (cp->textmap) setgdev(cp);
  2496. l = Color2Index(in);
  2497. i = l &0x0000ffff;
  2498. csave = *in;
  2499. if (i == 0) {
  2500.     csave = *in;
  2501.     InvertColor(&csave);
  2502.     *out = csave;
  2503.     }
  2504. else *out = *in;
  2505. if (cp->textmap) resetgdev();
  2506. }
  2507.  
  2508. void actualcolor(RGBColor *in, RGBColor *out, cnr *cp)
  2509.                 /* convert color to actual color displayed */
  2510. {
  2511. if (cp->textmap) setgdev(cp);
  2512. Index2Color(Color2Index(in), out);
  2513. if (cp->textmap) resetgdev();
  2514. }
  2515.  
  2516. void updevent(GrafPtr msgptr)
  2517. {
  2518. short txtmode;
  2519. GrafPtr gp;
  2520. BitMap * srcbits;
  2521. char statflg;
  2522. PixMapHandle currPM;
  2523. cnr *cp;
  2524. Rect r;
  2525.  
  2526. statflg = 0;
  2527. GetPort(&gp);
  2528. SetPort(msgptr);
  2529. if (mywindow(msgptr, &cp)) {
  2530.     SetClip(cp->cliprgn);
  2531.     }
  2532. BeginUpdate(msgptr);
  2533. if (mywindow(msgptr, &cp)) {
  2534.     if (cp->WritePtr != cp->myWindow) {
  2535.         if (colormac) {
  2536.             GetGlobalRect(cp->myWindow, &r);
  2537.             bitmap_gdev = myGetMaxDevice(&r);
  2538.             }
  2539.         if (RectInRgn(&cp->textRect, (cp->myWindow)->visRgn) && cp->needwrite) {
  2540.             SetPort(cp->WritePtr);
  2541.             setgdev(0);
  2542.             writescr(0, cp);
  2543.             resetgdev();
  2544.             SetPort(cp->myWindow);
  2545.             cp->needwrite = 0;
  2546.             if (cp->wr_active) statflg = 1;
  2547.             }
  2548.         if (colormac && (!cp->cs.nocolor)) {
  2549.             RGBForeColor(&realblack);
  2550.             RGBBackColor(&realwhite);
  2551.             }
  2552.         if (cp->drawpict && (cp->PictPtr != 0)) {
  2553.             if (colormac && (!cp->cs.nocolor))
  2554.                 srcbits = (BitMap *)(*(PixMapHandle)(cp->PictPort).portBits.baseAddr);
  2555.             else
  2556.                 srcbits = &(cp->PictPort).portBits;
  2557.             CopyBits(srcbits, &((cp->myWindow)->portBits),
  2558.                             &(cp->pictRect), &(cp->textRect), srcCopy, 0L);
  2559.             }
  2560.         if (colormac && (!cp->cs.nocolor))
  2561.             srcbits = (BitMap *)(*(PixMapHandle)(cp->WritePort).portBits.baseAddr);
  2562.         else
  2563.             srcbits = &(cp->WritePort).portBits;
  2564.         if (cp->drawpict) {
  2565.             if (colormac && (!cp->cs.nocolor)) {
  2566.                 currPM = (*bitmap_gdev)->gdPMap;
  2567.                 if ((*currPM)->pixelSize > 1) {
  2568.                     if (cp->cs.invertbw) txtmode = adMin;
  2569.                     else txtmode = adMax;
  2570.                     }
  2571.                 else {
  2572.                     if (cp->cs.invertbw) txtmode = srcOr;
  2573.                     else txtmode = notSrcBic;
  2574.                     }
  2575.                 }
  2576.             else {
  2577.                 txtmode = srcOr;
  2578.                 }
  2579.             CopyBits(srcbits, &((cp->myWindow)->portBits),
  2580.                      &(cp->textRect), &(cp->textRect), txtmode, 0L);
  2581.             CopyBits(srcbits, &((cp->myWindow)->portBits),
  2582.                      &(cp->statRect), &(cp->statRect), srcCopy, 0L);
  2583.             }
  2584.         else CopyBits(srcbits, &((cp->myWindow)->portBits),
  2585.                  &(cp->scrnRect), &(cp->scrnRect), srcCopy, 0L);
  2586.         drawcurs(0, cp);    /* draw cursor, no restore */
  2587.         if (RectInRgn(&(cp->gr_rect), (cp->myWindow)->visRgn)) justGrowIcon(1, cp);
  2588.         }
  2589.     else {
  2590.         if (RectInRgn(&(cp->textRect), (cp->myWindow)->visRgn)) {
  2591.             writescr(0, cp);
  2592.             cp->needwrite = 0;
  2593.             if (cp->wr_active) statflg = 1;
  2594.             }
  2595.         if (RectInRgn(&(cp->statRect), (cp->myWindow)->visRgn)) {
  2596.             statline(cp);
  2597.             }
  2598.         if (RectInRgn(&(cp->gr_rect), (cp->myWindow)->visRgn)) justGrowIcon(1, cp);
  2599.         }
  2600.     }
  2601. else if (myxfwindow(msgptr, &cp)) {    
  2602.         DrawDialog(cp->xdlgptr);
  2603.         xfGrowIcon(cp);
  2604.         }
  2605. EndUpdate(msgptr);
  2606. if (mywindow(msgptr, &cp)) SetClip(cp->destrgn);
  2607. SetPort(gp);
  2608. if (mywindow(msgptr, &cp)) {
  2609.     if (statflg) {
  2610.         cp->wr_active = 0;
  2611.         newstat(cp);
  2612.         }
  2613.     }
  2614. if (showstg) {
  2615.     showstg = 0;
  2616.     stginfo(front_cp());
  2617.     }
  2618. }
  2619.  
  2620. void mkPix(GrafPtr gptr, unsigned char **mptr, Rect *b_rect,
  2621.            GDHandle gdev, cnr *cp)
  2622. {
  2623.     GDHandle saveGD;
  2624.     Size mmapsize;
  2625.     Ptr temp;
  2626.     PixMapPtr pixptr;
  2627.     PixMapHandle devPM;
  2628.     CTabHandle myCTabHandle;
  2629.     OSErr memerr;
  2630.  
  2631.     saveGD = GetGDevice();
  2632.     SetGDevice(gdev);
  2633.     OpenCPort((CGrafPtr)gptr);
  2634.     pixptr = *(PixMapHandle)(gptr->portBits.baseAddr);
  2635.     pixptr->bounds = *b_rect;
  2636.     PortSize(pixptr->bounds.right, pixptr->bounds.bottom);
  2637.     SetRectRgn(gptr->visRgn, 0, 0, pixptr->bounds.right,
  2638.                 pixptr->bounds.bottom);
  2639.     devPM = (*gdev)->gdPMap;
  2640.     pixptr->rowBytes = ((((cp->hpixsize * (*devPM)->pixelSize) + 31) >> 5) + 1) << 2;
  2641.     mmapsize = pixptr->bounds.bottom - pixptr->bounds.top;
  2642.     mmapsize = mmapsize * pixptr->rowBytes + 4;
  2643.     cp->pictsize = mmapsize;
  2644.     *mptr = myNewPtr(mmapsize, cp);
  2645.     temp = *mptr;
  2646.     while (((Size)temp%4) != 0) temp++;    /* align on long word */
  2647.     pixptr = *(PixMapHandle)(gptr->portBits.baseAddr);
  2648.     pixptr->baseAddr = temp;
  2649.     if (pixptr->baseAddr == 0L) {        /* no bitmap */ 
  2650.         SetGDevice(saveGD);
  2651.         CloseCPort((CGrafPtr)gptr);
  2652.         return;
  2653.         }
  2654.     pixptr->rowBytes += 0x8000;
  2655.  
  2656.     /* set-up color table for our map */
  2657.     devPM = (*gdev)->gdPMap;
  2658.     myCTabHandle = (*devPM)->pmTable;
  2659.     memerr = HandToHand((Handle *)&myCTabHandle);
  2660.     if (memerr != 0) {
  2661.         SetGDevice(saveGD);
  2662.         DisposPtr(*mptr);
  2663.         *mptr = 0;
  2664.         CloseCPort((CGrafPtr)gptr);
  2665.         return;
  2666.         }
  2667.     pixptr = *(PixMapHandle)(gptr->portBits.baseAddr);
  2668.     pixptr->pmTable = myCTabHandle;
  2669.  
  2670.     /* miscellaneous stuff */
  2671.     
  2672.     ClipRect(&(gptr->portRect));
  2673.     EraseRect(&(gptr->portRect));
  2674.     SetOrigin(0, 0);
  2675.     TextFont(cp->stdfont);
  2676.     TextSize(cp->cur_ptsize);
  2677.     SetGDevice(saveGD);
  2678. }
  2679.  
  2680. Ptr myNewPtr(Size s, cnr *cp)
  2681. {
  2682. Ptr result;
  2683. long l, reserve;
  2684.  
  2685. result = NewPtr(s);
  2686. if (result == 0) return(result);
  2687.  
  2688. /* check there is still enough free storage for normal operation */
  2689. MaxApplZone();
  2690. l = FreeMem();
  2691. reserve = 32768;        /* need at least 32K in any case */
  2692. if (cp != 0) {
  2693.     if (cp->tcpflg) {                /* adjust for TCP/IP */
  2694.         reserve += tcpgetrsrv(cp);
  2695.         }
  2696.     else if (cp->serflg) {            /* adjust for serial */
  2697.         reserve += sergetrsrv(cp);
  2698.         }
  2699.     else {                            /* adjust for standalone */
  2700.         reserve += sagetrsrv(cp);
  2701.         }
  2702.     }
  2703. if (l < reserve) {
  2704.     DisposPtr(result);
  2705.     result = 0;
  2706.     }
  2707. return(result);
  2708. }
  2709.  
  2710. int updCTab(cnr *cp)            /* check for new color table */
  2711. {
  2712. GDHandle currGD;
  2713. PixMapHandle currPM, myPM;
  2714. CTabHandle currcth, mycth;
  2715. OSErr memerr;
  2716. Rect r;
  2717.  
  2718. if (!(cp->textmap)) return(0);
  2719.  
  2720. GetGlobalRect(cp->myWindow, &r);
  2721. currGD = myGetMaxDevice(&r);
  2722. currPM = (*currGD)->gdPMap;
  2723. currcth = (*currPM)->pmTable;
  2724.  
  2725. myPM = (PixMapHandle)((cp->WritePtr)->portBits.baseAddr);
  2726. mycth = (*myPM)->pmTable;
  2727.  
  2728. /* return if color table hasn't changed */
  2729. if ((*currcth)->ctSeed == (*mycth)->ctSeed) return(0);
  2730.  
  2731. /* return if pixel depth has changed */
  2732. if ((*myPM)->pixelSize != (*currPM)->pixelSize) return(0);
  2733.  
  2734. /* make my color table match the new one */
  2735. DisposHandle((Handle)mycth);
  2736.  
  2737. currGD = myGetMaxDevice(&r);
  2738. currPM = (*currGD)->gdPMap;
  2739. currcth = (*currPM)->pmTable;
  2740. myPM = (PixMapHandle)((cp->WritePtr)->portBits.baseAddr);
  2741.  
  2742. (*myPM)->pmTable = currcth;
  2743. memerr = HandToHand((Handle *)&((*myPM)->pmTable));
  2744. if (memerr != 0) {
  2745.     stgalert("text color table", "HandToHand", 0L);
  2746.     ExitToShell();
  2747.     }
  2748.  
  2749. /* repeat for graphics bitmap */
  2750. if (cp->PictPtr == 0) return(1);
  2751. myPM = (PixMapHandle)((cp->PictPtr)->portBits.baseAddr);
  2752. mycth = (*myPM)->pmTable;
  2753. /* make my color table match the new one */
  2754. DisposHandle((Handle)mycth);
  2755.  
  2756. currGD = myGetMaxDevice(&r);
  2757. currPM = (*currGD)->gdPMap;
  2758. currcth = (*currPM)->pmTable;
  2759. myPM = (PixMapHandle)((cp->PictPtr)->portBits.baseAddr);
  2760.  
  2761. (*myPM)->pmTable = currcth;
  2762. memerr = HandToHand((Handle *)&((*myPM)->pmTable));
  2763. if (memerr != 0) {
  2764.     stgalert("graphics color table", "HandToHand", 0L);
  2765.     ExitToShell();
  2766.     }
  2767. return(2);
  2768. }
  2769.  
  2770. int newCTab(cnr *cp)                /* check for new color table */
  2771. {
  2772. GDHandle currGD;
  2773. PixMapHandle currPM, myPM;
  2774. CTabHandle currcth, mycth;
  2775. Rect r;
  2776.  
  2777. if (!(cp->textmap)) return(0);
  2778.  
  2779. GetGlobalRect(cp->myWindow, &r);
  2780. currGD = myGetMaxDevice(&r);
  2781. currPM = (*currGD)->gdPMap;
  2782. currcth = (*currPM)->pmTable;
  2783.  
  2784. myPM = (PixMapHandle)((cp->WritePtr)->portBits.baseAddr);
  2785. mycth = (*myPM)->pmTable;
  2786.  
  2787. /* return 0 if color table hasn't changed */
  2788. if ((*currcth)->ctSeed == (*mycth)->ctSeed) return(0);
  2789.  
  2790. /* return 0 if pixel depth has changed */
  2791. if ((*myPM)->pixelSize != (*currPM)->pixelSize) return(0);
  2792.  
  2793. /* else return 1 */
  2794. return(1);
  2795. }
  2796.  
  2797. void rmPix(GrafPtr gptr, Ptr mptr)
  2798. {
  2799. PixMapPtr pixptr;
  2800.  
  2801.                                     /* dispose copy of color table */
  2802. pixptr = *(PixMapHandle)(gptr->portBits.baseAddr);
  2803. DisposHandle((Handle)pixptr->pmTable);
  2804. if (mptr != 0) DisposPtr(mptr);
  2805. pixptr->baseAddr = 0;
  2806. CloseCPort((CGrafPtr)gptr);
  2807. }
  2808.  
  2809. void newinvbw(cnr *cp)        /* make updates to handle a new value of invbw */
  2810. {
  2811. if ((!colormac) || cp->cs.nocolor) return;
  2812.  
  2813. if (cp->cs.invertbw) {
  2814.     if (cp->curnum > 20846) cp->curnum -= 2;
  2815.     else return;
  2816.     }
  2817. else {
  2818.     if (cp->curnum < 20847) cp->curnum += 2;
  2819.     else return;
  2820.     }
  2821. cp->grafcursor = GetCursor(cp->curnum);
  2822. dfltcurs = 2;        /* force SetCursor call */
  2823. }
  2824.  
  2825. void newbackcolor(cnr *cp)
  2826. {
  2827. RGBColor rgbtemp;
  2828. GrafPtr gp;
  2829.  
  2830. GetEntryColor(cp->myPalette, RGBback, &rgbtemp);
  2831. GetPort(&gp);
  2832. SetPort(cp->WritePtr);
  2833. if (cp->textmap) setgdev(cp);
  2834. RGBBackColor(&rgbtemp);
  2835. if (cp->PictPtr != 0) {
  2836.     SetPort(cp->PictPtr);
  2837.     RGBBackColor(&rgbtemp);
  2838.     }
  2839. SetPort(gp);
  2840. if (cp->textmap) resetgdev();
  2841. }
  2842.  
  2843. void setgdev(cnr *cp)
  2844. {
  2845. Rect r;
  2846.  
  2847. if (!colormac) return;
  2848. if (cp != 0) {
  2849.     if (cp->myWindow != 0) {
  2850.         GetGlobalRect(cp->myWindow, &r);
  2851.         bitmap_gdev = myGetMaxDevice(&r);
  2852.         }
  2853.     }
  2854. saved_gdev = GetGDevice();
  2855. SetGDevice(bitmap_gdev);
  2856. }
  2857.  
  2858. void resetgdev(void)
  2859. {
  2860. if (!colormac) return;
  2861. SetGDevice(saved_gdev);
  2862. }
  2863.  
  2864. void adjfmt(char *changed, char *windmax, short *dfltptsize,
  2865.             short *altptsize, short *altrows, short *altcols)
  2866. /* adjust screen format settings to be valid for the current set of gdevs */
  2867. {
  2868. #pragma unused (windmax)
  2869. char altok;
  2870. short altsize, newptsize, newrows, newcols, maxrows, maxcols;
  2871.  
  2872. (*changed) = 0;
  2873.  
  2874. /* set default point size to 9 if 24-by-80 won't fit with 12-point */
  2875. if ((rowmax12 < 24) || (colmax12 < 80)) {
  2876.     if ((*dfltptsize) == 12) {
  2877.         (*dfltptsize) = 9;
  2878.         (*changed) = 1;
  2879.         }
  2880.     }
  2881. /* check alternate screen size is valid */
  2882. if ((*altrows) < 24) {
  2883.     (*altrows) = 24;
  2884.     (*changed) = 1;
  2885.     }
  2886. if ((*altcols) < 80) {
  2887.     (*altcols) = 80;
  2888.     (*changed) = 1;
  2889.     }
  2890.  
  2891. /* check if alternate screen size will fit */
  2892. if ((*altptsize) == 9) {
  2893.     altok = (((*altrows) <= rowmax9) && ((*altcols) <= colmax9));
  2894.     }
  2895. else {
  2896.     altok = (((*altrows) <= rowmax12) && ((*altcols) <= colmax12));
  2897.     }
  2898. /* if not, and 12-point specified, try 9-point */
  2899. if (((*altptsize) == 12) && (!altok)) {
  2900.     altok = (((*altrows) <= rowmax9) && ((*altcols) <= colmax9));
  2901.     if (altok) {
  2902.         (*altptsize) = 9;    
  2903.         (*changed) = 1;
  2904.         }
  2905.     }
  2906. if (altok) {
  2907.     return;
  2908.     }
  2909.     
  2910. /* find the closest standard model that will fit, and use the largest point
  2911.    size for that model */
  2912.  
  2913. altsize = (*altrows) * (*altcols);
  2914. if ((altsize >= 3564) && ((*altcols) > 80)) {
  2915.     newrows = 27;    /* model 5 */
  2916.     newcols = 132;
  2917.     }
  2918. else if (altsize >= 3440) {
  2919.     newrows = 43;    /* model 4 */
  2920.     newcols = 80;
  2921.     }
  2922. else if (altsize >= 2560) {
  2923.     newrows = 32;    /* model 3 */
  2924.     newcols = 80;
  2925.     }
  2926. else {
  2927.     newrows = 24;    /* model 2 */
  2928.     newcols = 80;
  2929.     }
  2930. newptsize = 12;
  2931. maxrows = rowmax12;
  2932. maxcols = colmax12;
  2933. while ((newrows > 24) || (newptsize > 9)) {
  2934.     /* test this model/ptsize */
  2935.     if ((newrows <= maxrows) && (newcols <= maxcols)) break; 
  2936.     /* set next model/ptsize */
  2937.     if (newptsize == 12) {
  2938.         newptsize = 9;
  2939.         maxrows = rowmax9;
  2940.         maxcols = colmax9;
  2941.         }
  2942.     else {
  2943.         newptsize = 12;
  2944.         maxrows = rowmax12;
  2945.         maxcols = colmax12;
  2946.         newcols = 80;
  2947.         if (newrows == 27) newrows = 43;
  2948.         else if (newrows == 43) newrows = 32;
  2949.         else if (newrows == 32) newrows = 24;
  2950.         }
  2951.     }
  2952. (*altptsize) = newptsize;
  2953. (*altrows) = newrows;
  2954. (*altcols) = newcols;
  2955. (*changed) = 1;
  2956. }
  2957.  
  2958. void newstdfont(short f, cnr *cp)
  2959. {
  2960. GrafPtr gp;
  2961.  
  2962. cp->stdfont = f;
  2963. cp->fixbracket = cp->cs.std_brack && (!(cp->aplmode)) && (cp->stdfont != ALAFONT);
  2964. if (cp->myWindow == 0) return;
  2965. GetPort(&gp);
  2966. SetPort(cp->myWindow);
  2967. TextFont(f);
  2968. if (cp->WritePtr != 0) {
  2969.     SetPort(cp->WritePtr);
  2970.     TextFont(f);
  2971.     }
  2972. if (cp->PictPtr != 0) {
  2973.     SetPort(cp->PictPtr);
  2974.     TextFont(f);
  2975.     }
  2976. SetPort(gp);
  2977. }
  2978.  
  2979. void updwindpos(cnr *cp)
  2980. {
  2981. Point p;
  2982. GrafPtr gp;
  2983.  
  2984. if (cp->myWindow == 0) return;
  2985.  
  2986. p.h = ((cp->myWindow)->portRect.right + (cp->myWindow)->portRect.left + 1)/2;
  2987. p.v = ((cp->myWindow)->portRect.bottom + (cp->myWindow)->portRect.top - 17)/2;
  2988. GetPort(&gp);
  2989. SetPort(cp->myWindow);
  2990. LocalToGlobal(&p);        /* global current center */
  2991. SetPort(gp);
  2992. cp->cs.windpth = p.h;
  2993. cp->cs.windptv = p.v;
  2994. cp->wposok = 1;
  2995. }
  2996.